From: Atsushi Eno Date: Fri, 19 Nov 2010 03:28:01 +0000 (+0900) Subject: Merge branch 'xml-fixes' of https://github.com/myeisha/mono into myeisha-xml-fixes X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=292eea651d0ee9a04a0da41165aef38fbdbc5c6b;hp=5150ffd9f37337b838d0b4ed049ed69b467c27d2;p=mono.git Merge branch 'xml-fixes' of https://github.com/myeisha/mono into myeisha-xml-fixes --- diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index f2f2089f386..00000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,3093 +0,0 @@ -cmake_minimum_required(VERSION 2.6.4) - -# To keep this in sync with the autoconf based system: -# git log -n --format=oneline CMakeLists.txt -# git diff ..HEAD configure.in Makefile.am - -# FIXME: Sanitize the variables, no need for the duplicate am conditionals -# - It would be nice to rename 'CMakeFiles' to something like '.cmake' -# - It would be nice to have a per-target VERBOSE setting -# - or a way to change the setting name to 'V' and the output to CC -# to be similar to the current build output -# - Add a cache to the manual checks - -# We use lowercase commands as advocated by the kde cmake coding style - -include(CheckIncludeFile) -include(CheckCSourceCompiles) - -# Implementation of AC_CHECK_HEADERS -# In addition, it also records the list of variables in the variable -# 'autoheader_vars', and for each variable, a documentation string in the -# variable ${var}_doc -function(ac_check_headers headers) - foreach (header ${ARGV}) - string(TOUPPER ${header} header_var) - string(REPLACE "." "_" header_var ${header_var}) - string(REPLACE "/" "_" header_var ${header_var}) - set(header_var "HAVE_${header_var}") - check_include_file (${header} ${header_var}) - set("${header_var}_doc" "Define to 1 if you have the <${header}> header file." PARENT_SCOPE) - if (${header_var}) - set("${header_var}_defined" "1" PARENT_SCOPE) - endif() - set("${header_var}_val" "1" PARENT_SCOPE) - set (autoheader_vars ${autoheader_vars} ${header_var}) - endforeach() - set (autoheader_vars ${autoheader_vars} PARENT_SCOPE) -endfunction() - -function(ac_check_funcs funcs) - foreach (func ${ARGV}) - string(TOUPPER ${func} var) - set(var "HAVE_${var}") - set(${var}) - check_function_exists (${func} ${var}) - set("${var}_doc" "Define to 1 if you have the '${func}' function." PARENT_SCOPE) - if (${var}) - set("${var}_defined" "1" PARENT_SCOPE) - set(${var} yes PARENT_SCOPE) - endif() - set("${var}_val" "1" PARENT_SCOPE) - set (autoheader_vars ${autoheader_vars} ${var}) - endforeach() - set (autoheader_vars ${autoheader_vars} PARENT_SCOPE) -endfunction() - -# Implementation of AC_DEFINE -function(ac_define varname value doc) - if (${varname} MATCHES ",") - message(FATAL_ERROR ",") - endif() - set("${varname}_doc" ${doc} PARENT_SCOPE) - set("${varname}_defined" 1 PARENT_SCOPE) - set("${varname}_val" ${value} PARENT_SCOPE) - set (autoheader_vars ${autoheader_vars} ${varname} PARENT_SCOPE) -endfunction() - -# Implementation of AC_DEFINE_UNQUOTED -function(ac_define_unquoted varname value doc) - if (${varname} MATCHES ",") - message(FATAL_ERROR ",") - endif() - set("${varname}_doc" ${doc} PARENT_SCOPE) - set("${varname}_defined" 1 PARENT_SCOPE) - set("${varname}_val" \"${value}\" PARENT_SCOPE) - set (autoheader_vars ${autoheader_vars} ${varname} PARENT_SCOPE) -endfunction() - -Include(CheckTypeSize) - -# Implementation of AC_CHECK_SIZEOF -# FIXME: cross compiling -function(ac_check_sizeof type) - check_type_size(${type} size) - if (HAVE_size STREQUAL "TRUE") - else() - message(FATAL_ERROR "Type ${type} not found.") - endif() - string(TOUPPER "SIZEOF_${type}" varname) - string(REPLACE " " "_" varname ${varname}) - string(REPLACE "*" "P" varname ${varname}) - - set("${varname}_doc" "The size of '${type}' as computed by sizeof" PARENT_SCOPE) - set("${varname}_defined" 1 PARENT_SCOPE) - set("${varname}_val" ${size} PARENT_SCOPE) - set (autoheader_vars ${autoheader_vars} ${varname} PARENT_SCOPE) -endfunction() - -# Implementation of autoheader -function(AUTOHEADER filename variables) - set(tmp_filename "${filename}.tmp") - file(WRITE ${tmp_filename} "") - foreach(var ${${variables}}) - file(APPEND ${tmp_filename} "\n/* ${${var}_doc} */\n") - if(${${var}_defined}) - file(APPEND ${tmp_filename} "#define ${var} ${${var}_val}\n") - else() - file(APPEND ${tmp_filename} "/* #undef ${var} */\n") - endif() - endforeach() - # FIXME: This is unix specific - execute_process(COMMAND diff ${filename} ${filename}.tmp RESULT_VARIABLE diff_res OUTPUT_QUIET) - if (NOT diff_res STREQUAL 0) - message(STATUS "generating ${filename}.") - execute_process(COMMAND mv ${filename}.tmp ${filename}) - else() - message(STATUS "${filename} is unchanged.") - endif() -endfunction() - -function(ac_msg_checking) - message(STATUS "checking ${ARGV}...") - set(last_msg_checking ${ARGV} PARENT_SCOPE) -endfunction() - -function(ac_msg_result) - message(STATUS "checking ${last_msg_checking}... ${ARGV}") -endfunction() - -function(ac_msg_error) - message(FATAL_ERROR "${ARGV}") -endfunction() - -function(ac_msg_warn) - message(STATUS "WARNING: ${ARGV}") -endfunction() - -# The lines commented out using ### are the stuff from configure.in which still -# need to be ported to cmake - -set(VERSION 2.7) -ac_define_unquoted(VERSION ${VERSION} "Version number of package") -set(API_VER 1.0) -### -###AC_PROG_LN_S -### -#### In case of cygwin, override LN_S, irrespective of what it determines. -#### The build uses cygwin, but the actual runtime doesn't. -###case $host_os in -###*cygwin* ) set(LN_S 'cp -p';;) -###esac -### -### - -# -# These variables are the CPPFLAGS/CFLAGS passed to libgc's configure -# libgc should inherit the original CFLAGS/CPPFLAGS passed to configure, i.e. -O0 -# -set(CPPFLAGS_FOR_LIBGC ${CPPFLAGS}) -set(CFLAGS_FOR_LIBGC ${CFLAGS}) - -# -# These are the flags that need to be stored in the mono.pc file for -# compiling code that will embed Mono -# -set(libmono_cflags "") -set(libmono_ldflags "") - -###AC_SUBST(libmono_cflags) -###AC_SUBST(libmono_ldflags) -### -#### Variable to have relocatable .pc files (lib, or lib64) -###set(reloc_libdir `basename ${libdir}`) -###AC_SUBST(reloc_libdir) - -# if linker handles the version script -set(no_version_script no) - -# Set to yes if Unix sockets cannot be created in an anonymous namespace -set(need_link_unlink no) - -# -# Platform support -# - -# Obtain the GNU style target -# From GetTargetTriple.cmake in LLVM -function( get_target_triple var ) - if( MSVC ) - set( ${var} "i686-pc-win32" PARENT_SCOPE ) - else( MSVC ) - set(config_guess config.guess) - execute_process(COMMAND sh ${config_guess} - RESULT_VARIABLE TT_RV - OUTPUT_VARIABLE TT_OUT - OUTPUT_STRIP_TRAILING_WHITESPACE) - if( NOT TT_RV EQUAL 0 ) - message(FATAL_ERROR "Failed to execute ${config_guess}") - endif( NOT TT_RV EQUAL 0 ) - set( ${var} ${TT_OUT} PARENT_SCOPE ) - endif( MSVC ) -endfunction( get_target_triple var ) - -get_target_triple(host) - -message(STATUS "checking host platform characteristics...") - -set(libgc_threads no) -set(has_dtrace no) -set(parallel_mark yes) - -if(host MATCHES .*-.*-linux.*) - set(platform_win32 no) - set(CPPFLAGS "${CPPFLAGS} -DHAVE_CONFIG_H -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP") - set(libmono_cflags "-D_REENTRANT") - set(libmono_ldflags "-lpthread") - set(libdl "-ldl") - set(libgc_threads pthreads) - set(AOT_SUPPORTED "yes") - set(use_sigposix yes) -else() - message(FATAL_ERROR "The cmake build doesn't yet support host '${host}'.") -endif() - -#### Thread configuration inspired by sleepycat's db -###case "$host" in -### *-*-mingw*|*-*-cygwin*) -### set(platform_win32 yes) -### AC_DEFINE(PLATFORM_WIN32,1,[Host Platform is Win32]) -### AC_DEFINE(TARGET_WIN32,1,[Target OS is Win32]) -### ac_define(DISABLE_PORTABILITY,1,[Disable the io-portability layer]) -### ac_define(PLATFORM_NO_SYMLINKS,1,[This platform does not support symlinks]) -### if test "x$cross_compiling" = "xno"; then -### set(CC "gcc -mno-cygwin -g") -### # So libgc configure gets -mno-cygwin -### export CC -### fi -### set(HOST_CC "gcc") -### # Windows 2000 is required that includes Internet Explorer 5.01 -### set(CPPFLAGS "$CPPFLAGS -DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0501 -D_UNICODE -DUNICODE -DWIN32_THREADS -DFD_SETSIZE=1024") -### set(libmono_cflags "-mno-cygwin -mms-bitfields -mwindows") -### set(libmono_ldflags "-mno-cygwin -mms-bitfields -mwindows") -### set(libdl ) -### set(libgc_threads win32) -### set(gc_default included) -### set(with_sigaltstack no) -### set(LN_S cp) -### # This forces libgc to use the DllMain based thread registration code on win32 -### set(libgc_configure_args "$libgc_configure_args --enable-win32-dllmain=yes") -### ;; -### *-*-*netbsd*) -### set(platform_win32 no) -### set(CPPFLAGS "$CPPFLAGS -D_REENTRANT -DGC_NETBSD_THREADS -D_GNU_SOURCE") -### set(libmono_cflags "-D_REENTRANT") -### set(LDFLAGS "$LDFLAGS -pthread") -### set(CPPFLAGS "$CPPFLAGS -DPLATFORM_BSD") -### set(libmono_ldflags "-pthread") -### set(need_link_unlink yes) -### set(libdl "-ldl") -### set(libgc_threads pthreads) -### set(with_sigaltstack no) -### set(use_sigposix yes) -### ;; -### *-*-*freebsd*) -### set(platform_win32 no) -### if test "x$PTHREAD_CFLAGS" = "x"; then -### set(CPPFLAGS "$CPPFLAGS -DGC_FREEBSD_THREADS") -### set(libmono_cflags ) -### else -### set(CPPFLAGS "$CPPFLAGS $PTHREAD_CFLAGS -DGC_FREEBSD_THREADS") -### set(libmono_cflags "$PTHREAD_CFLAGS") -### fi -### if test "x$PTHREAD_LIBS" = "x"; then -### set(LDFLAGS "$LDFLAGS -pthread") -### set(libmono_ldflags "-pthread") -### else -### set(LDFLAGS "$LDFLAGS $PTHREAD_LIBS") -### set(libmono_ldflags "$PTHREAD_LIBS") -### fi -### set(CPPFLAGS "$CPPFLAGS -DPLATFORM_BSD") -### set(need_link_unlink yes) -### ac_define(PTHREAD_POINTER_ID, 1, [pthread is a pointer]) -### set(libdl ) -### set(libgc_threads pthreads) -### # This doesn't seem to work as of 7.0 on amd64 -### set(with_sigaltstack no) -#### TLS is only partially implemented on -CURRENT (compiler support -#### but NOT library support) -#### -### set(with_tls pthread) -### set(use_sigposix yes) -### ;; -### *-*-*openbsd*) -### set(platform_win32 no) -### set(CPPFLAGS "$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS -DPLATFORM_BSD") -### set(libmono_cflags "-D_THREAD_SAFE") -### set(LDFLAGS "$LDFLAGS -pthread") -### set(libmono_ldflags "-pthread") -### set(need_link_unlink yes) -### ac_define(PTHREAD_POINTER_ID) -### set(libdl ) -### set(libgc_threads pthreads) -### set(use_sigposix yes) -### ;; -### *-*-linux*) -### set(platform_win32 no) -### set(CPPFLAGS "$CPPFLAGS -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP") -### set(libmono_cflags "-D_REENTRANT") -### set(libmono_ldflags "-lpthread") -### set(libdl "-ldl") -### set(libgc_threads pthreads) -### set(AOT_SUPPORTED "yes") -### set(use_sigposix yes) -### ;; -### *-*-hpux*) -### set(platform_win32 no) -### set(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 -### if test $GCC != "yes"; then -### set(CFLAGS "$CFLAGS +ESdbgasm") -### # Arrange for run-time dereferencing of null -### # pointers to produce a SIGSEGV signal. -### set(LDFLAGS "$LDFLAGS -z") -### fi -### set(CFLAGS "$CFLAGS +ESdbgasm") -### set(LDFLAGS "$LDFLAGS -z") -### set(libmono_cflags "-D_REENTRANT") -### set(libmono_ldflags "-lpthread") -### set(libgc_threads pthreads) -### set(need_link_unlink yes) -### set(use_sigposix yes) -### ;; -### *-*-solaris*) -### set(platform_win32 no) -### set(CPPFLAGS "$CPPFLAGS -DGC_SOLARIS_THREADS -DGC_SOLARIS_PTHREADS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_MMAP -DUSE_MUNMAP -DPLATFORM_SOLARIS") -### set(need_link_unlink yes) -### set(libmono_cflags "-D_REENTRANT") -### set(libgc_threads pthreads) -### # This doesn't seem to work on solaris/x86, but the configure test runs -### set(with_tls pthread) -### set(has_dtrace yes) -### set(use_sigposix yes) -### ;; -### *-*-darwin*) -### set(parallel_mark "Disabled_Currently_Hangs_On_MacOSX") -### set(platform_win32 no) -### set(platform_darwin yes) -### set(CPPFLAGS "$CPPFLAGS -no-cpp-precomp -D_THREAD_SAFE -DGC_MACOSX_THREADS -DPLATFORM_MACOSX -DUSE_MMAP -DUSE_MUNMAP") -### set(CPPFLAGS "$CPPFLAGS -DGetCurrentProcess=MonoGetCurrentProcess -DGetCurrentThread=MonoGetCurrentThread -DCreateEvent=MonoCreateEvent") -### set(libmono_cflags "-D_THREAD_SAFE") -### set(LDFLAGS "$LDFLAGS -pthread") -### set(libmono_ldflags "-pthread") -### set(need_link_unlink yes) -### ac_define(PTHREAD_POINTER_ID) -### ac_define(USE_MACH_SEMA, 1, [...]) -### set(no_version_script yes) -### set(libdl ) -### set(libgc_threads pthreads) -### set(has_dtrace yes) -### if test "x$cross_compiling" = "xyes"; then -### set(has_broken_apple_cpp yes) -### fi -### ;; -### *) -### AC_MSG_WARN([*** Please add $host to configure.in checks!]) -### set(platform_win32 no) -### set(libdl "-ldl") -### ;; -###esac -###AC_MSG_RESULT(ok) -### -###if test x$need_link_unlink = xyes; then -### ac_define(NEED_LINK_UNLINK, 1, [Define if Unix sockets cannot be created in an anonymous namespace]) -###fi -### - -if(use_sigposix) - set(PLATFORM_SIGPOSIX 1) -endif() -if(platform_win32) - set(HOST_WIN32 yes) - set(TARGET_WIN32 yes) -endif() -if(${target_os} MATCHES "*linux*") - set(PLATFORM_LINUX yes) -endif() -if(platform_darwin) - set(PLATFORM_DARWIN yes) -endif() - -include(CMakeDetermineASM-ATTCompiler) - -find_program(BISON NAMES bison) - -if(BISON STREQUAL "BISON-NOTFOUND") - message(FATAL_ERROR "You need to install bison") -else() - message(STATUS "Found bison: ${BISON}") -endif() - -###AC_PROG_INSTALL -###AC_PROG_AWK -#### We should use AM_PROG_AS, but it's not available on automake/aclocal 1.4 -###: ${set(CCAS '$(CC)'}) -#### Set ASFLAGS if not already set. -###: ${set(CCASFLAGS '$(CFLAGS)'}) -###AC_SUBST(CCAS) -###AC_SUBST(CCASFLAGS) -### -#### may require a specific autoconf version -#### AC_PROG_CC_FOR_BUILD -#### CC_FOR_BUILD not automatically detected -###set(CC_FOR_BUILD $CC) -###set(CFLAGS_FOR_BUILD $CFLAGS) -###set(BUILD_EXEEXT ) -###if test "x$cross_compiling" = "xyes"; then -### set(CC_FOR_BUILD cc) -### set(CFLAGS_FOR_BUILD ) -### set(BUILD_EXEEXT "") -###fi -###AC_SUBST(CC_FOR_BUILD) -###AC_SUBST(CFLAGS_FOR_BUILD) -###AC_SUBST(HOST_CC) -###AC_SUBST(BUILD_EXEEXT) -### -###AM_CONDITIONAL(CROSS_COMPILING, [test x$cross_compiling = xyes]) -###AM_CONDITIONAL(USE_BATCH_FILES, [test x$platform_win32 = xyes -a x$cross_compiling = xyes]) -### -#### Set STDC_HEADERS -###AC_HEADER_STDC -###AC_LIBTOOL_WIN32_DLL -#### This causes monodis to not link correctly -####AC_DISABLE_FAST_INSTALL -###set(export_ldflags `(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`) -###AC_SUBST(export_ldflags) -### -#### Test whenever ld supports -version-script -###AC_PROG_LD -###AC_PROG_LD_GNU -###if test "x$lt_cv_prog_gnu_ld" = "xno"; then -### set(no_version_script yes) -###fi -### -###AM_CONDITIONAL(NO_VERSION_SCRIPT, test x$no_version_script = xyes) -### - -ac_check_headers(unistd.h stdint.h sys/types.h) -ac_check_headers(sys/filio.h sys/sockio.h netdb.h utime.h sys/utime.h semaphore.h sys/un.h linux/rtc.h sys/syscall.h sys/mkdev.h) -ac_check_headers(sys/user.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h) - -ac_check_headers(zlib.h) -set(have_zlib ${HAVE_ZLIB_H}) -if(have_zlib) - set(compiles) - check_c_source_compiles(" -#include -void main () { -#if defined(ZLIB_VERNUM) && (ZLIB_VERNUM >= 0x1230) -} -#else -#error No good zlib found -#endif -" compiles) - if(compiles) - ac_msg_result("Using system zlib") - set(zlib_msg "system zlib") - set(HAVE_ZLIB yes) - else() - ac_msg_result("Using embedded zlib") - set(have_zlib no) - set(zlib_msg "bundled zlib") - endif() -endif() - -if(have_zlib) - set(HAVE_ZLIB yes) -endif() -ac_define(HAVE_ZLIB 1 "Have system zlib") - -# for mono/metadata/debug-symfile.c -ac_check_headers(elf.h) - -# for support -ac_check_headers(poll.h) -ac_check_headers(sys/poll.h) -ac_check_headers(sys/wait.h) -ac_check_headers(grp.h) -ac_check_headers(syslog.h) - -# for mono/dis -ac_check_headers(wchar.h) -ac_check_headers(ieeefp.h) - -# Check whenever using GCC -include(CheckCSourceCompiles) -include(CheckCCompilerFlag) -check_c_source_compiles(" -#ifdef __GNUC__ -#else -#error 1 -#endif -void main () {} -" GCC) - -if(NOT HAVE_ISINF) - ac_msg_checking("for isinf") - set(compiles) - check_c_source_compiles(" -#include -void main () { -int f = isinf (1); -} -" compiles) - if(compiles) - ac_msg_result(yes) - ac_define(HAVE_ISINF 1 "isinf available") - set(HAVE_ISINF 1 CACHE BOOL "Have the isinf function") - else() - ac_msg_result(no) - endif() -endif() - -# not 64 bit clean in cross-compile -ac_check_sizeof("void *" 4) - -set(WARN '') - -if(GCC) - set(WARN "-Wall -Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual -Wwrite-strings") - # The runtime code does not respect ANSI C strict aliasing rules - set(CFLAGS "${CFLAGS} -fno-strict-aliasing") - CHECK_C_COMPILER_FLAG("-Wdeclaration-after-statement" HAS_WDECL_AFTER_STATEMENT) - if(HAS_WDECL_AFTER_STATEMENT) - set(WARN "${WARN} -Wdeclaration-after-statement") - endif() -else() - # The Sun Forte compiler complains about inline functions that access static variables - # so disable all inlining. -### case "$host" in -### *-*-solaris*) -### set(CFLAGS "$CFLAGS -Dinline=") -### ;; -### esac -###fi -endif() - -set(CFLAGS "${CFLAGS} -g ${WARN}") - -###set(CFLAGS_FOR_LIBGC "$CFLAGS_FOR_LIBGC -g") -### - -set(srcdir ${CMAKE_SOURCE_DIR}) -set(top_srcdir ${CMAKE_SOURCE_DIR}) -set(abs_top_srcdir ${top_srcdir}) - -# FIXME: -set(top_builddir ${CMAKE_BINARY_DIR}) - -# Where's the 'mcs' source tree? -if(EXISTS ${srcdir}/mcs) - set(mcsdir mcs) -else() - set(mcsdir ../mcs) -endif() - -# -# A sanity check to catch cases where the package was unpacked -# with an ancient tar program (Solaris) -# -set(solaris-tar-check yes CACHE BOOL "Enable/disable solaris tar check") - -if(solaris-tar-check) - ac_msg_checking("integrity of package") - if(EXISTS ${srcdir}/${mcsdir}/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapper.cs) - ac_msg_result(ok) - else() - set(errorm "Your mono distribution is incomplete; if unpacking from a tar file, make sure you use GNU tar; see http://www.mono-project.com/IncompletePackage for more details") - ac_msg_error(${errorm}) - endif() -endif() - -set(mcs_topdir ${top_srcdir}/${mcsdir}) -set(mcs_topdir_from_srcdir ${top_builddir}/${mcsdir}) -### -##### Maybe should also disable if mcsdir is invalid. Let's punt the issue for now. -###AM_CONDITIONAL(BUILD_MCS, [test x$cross_compiling = xno && test x$enable_mcs_build != xno]) -### -###AC_SUBST([mcs_topdir]) -###AC_SUBST([mcs_topdir_from_srcdir]) -### -#### Where's the 'olive' source tree? -###if test -d $srcdir/olive; then -### set(olivedir olive) -###else -### set(olivedir ../olive) -###fi -### -###if test -d $srcdir/$olivedir; then -###set(olive_topdir '$(top_srcdir)/'$olivedir) -###fi -### -#### gettext: prepare the translation directories. -#### we do not configure the full gettext, as we consume it dynamically from C# -###AM_PO_SUBDIRS -### -###if test "x$USE_NLS" = "xyes"; then -### AC_CHECK_PROG(HAVE_MSGFMT, msgfmt,yes,no) -### -### if test "x$HAVE_MSGFMT" = "xno"; then -### ac_msg_error([msgfmt not found. You need to install the 'gettext' package, or pass --enable-set(nls no to configure.])) -### fi -###fi -### -set(libgdiplus installed CACHE STRING "=installed|sibling| Override the libgdiplus used for System.Drawing tests (defaults to installed)") -set(with_libgdiplus ${libgdiplus}) - -###case $with_libgdiplus in -###no|installed) set(libgdiplus_loc ;;) -###yes|sibling) set(libgdiplus_loc `cd ../libgdiplus && pwd`/src/libgdiplus.la ;;) -###/*) set(libgdiplus_loc $with_libgdiplus ;;) -###*) set(libgdiplus_loc `pwd`/$with_libgdiplus ;;) -###esac -###AC_SUBST([libgdiplus_loc]) -### -### -###set(pkg_config_path ) -###set(crosspkgdir, [ --with-set(crosspkgdir /path/to/pkg-config/dir Change pkg-config dir to custom dir],) -### if test x$with_crosspkgdir = "x"; then -### if test -s $PKG_CONFIG_PATH; then -### set(pkg_config_path $PKG_CONFIG_PATH) -### fi -### else -### set(pkg_config_path $with_crosspkgdir) -### set(PKG_CONFIG_PATH $pkg_config_path) -### export PKG_CONFIG_PATH -### fi -###) -### -###set([glib], -### [ --with-set(glib embedded|system Choose glib API: system or embedded (default to system)],) -### [], [set(with_glib system])) -### -###set(eglib_dir ) -### - -include(FindPkgConfig) - -# FIXME: -set(with_glib "system") -if (${with_glib} STREQUAL "system") - ### if test "x$cross_compiling" = "xyes"; then - ### set(pkg_config_path "$PKG_CONFIG_PATH") - ### unset PKG_CONFIG_PATH - ### fi - PKG_CHECK_MODULES(GLIB2 REQUIRED glib-2.0 gthread-2.0) - set(BUILD_GLIB_CFLAGS ${GLIB2_CFLAGS}) - set(BUILD_GLIB_LIBS ${GLIB2_LIBRARIES}) - - ### if test "x$cross_compiling" = "xyes"; then - ### set(PKG_CONFIG_PATH $pkg_config_path) - ### export PKG_CONFIG_PATH - ### fi - ### - ## Versions of dependencies - set(GLIB_REQUIRED_VERSION 2.4.0) - - PKG_CHECK_MODULES(GLIB2 REQUIRED glib-2.0 >= ${GLIB_REQUIRED_VERSION} gthread-2.0) - set(GLIB_CFLAGS ${GLIB2_CFLAGS}) - set(GLIB_LIBS ${GLIB2_LIBRARIES}) - PKG_CHECK_MODULES(GMODULE REQUIRED gmodule-2.0) - set(GMODULE_CFLAGS ${GMODULE_CFLAGS}) - set(GMODULE_LIBS ${GMODULE_LIBRARIES}) -endif() - -###case $with_glib in -###embedded) -### set(GLIB_CFLAGS '-I$(top_srcdir)/eglib/src -I$(top_builddir)/eglib/src') -### set(GLIB_LIBS '-L$(top_builddir)/eglib/src -leglib -lm') -### set(BUILD_GLIB_CFLAGS "$GLIB_CFLAGS") -### set(BUILD_GLIB_LIBS "$GLIB_LIBS") -### set(GMODULE_CFLAGS "$GLIB_CFLAGS") -### set(GMODULE_LIBS "$GLIB_LIBS") -### set(eglib_dir eglib) -### AC_CONFIG_SUBDIRS(eglib) -### ;; -###*) -### ac_msg_error([Invalid argument to --with-glib.]) -###esac -if(with_glib STREQUAL "embedded") - set(EGLIB_BUILD yes) -endif() -### -###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) -###AC_SUBST(eglib_dir) -### -###if test x$cross_compiling$platform_win32 = xnoyes; then -### ac_msg_checking(for cygwin glib2-dev package) -### if [ cygcheck --f /usr/lib/libglib-2.0.dll.a | grep -q glib2-devel ]; then -### ac_msg_result(found) -### ac_msg_error([Mono cannot be built with the cygwin glib2-devel package installed, because that package doesn't work with -mno-cygwin. Please uninstall it then re-run configure.]) -### else -### ac_msg_result(not found, ok) -### fi -### -### ac_msg_checking(for broken gwin32.h) -### set(glib_include `$PKG_CONFIG --cflags-only-I glib-2.0 | sed -e 's/ -I.*//g' | sed -e 's/-I//g'`) -### if test -f $glib_include/glib/gwin32.h; then -### if [ grep ftruncate $glib_include/glib/gwin32.h | grep -q define ]; then -### ac_msg_result(failed) -### set(hashmark '#') -### ac_msg_error([Your version of gwin32.h is broken and will cause compilation errors when building mono. Please fix it by deleting the line: '$hashmark define ftruncate...' from '$glib_include/glib/gwin32.h' then re-run configure.]) -### fi -### fi -### ac_msg_result(ok) -###fi - -# Enable support for fast thread-local storage -# Some systems have broken support, so we allow to disable it. -set(tls __thread CACHE STRING "Select Thread Local Storage implementation. Possible values are '__thread_' and 'pthread' (defaults to __thread)") -set(with_tls ${tls}) - -# Enable support for using sigaltstack for SIGSEGV and stack overflow handling -# This does not work on some platforms (bug #55253) -set(sigaltstack yes CACHE BOOL "Enable/disable support for sigaltstack (defaults to yes)") -set(with_sigaltstack ${sigaltstack}) - -set(static_mono yes CACHE BOOL "Link mono statically to libmono (faster) (defaults to yes)") -set(with_static_mono ${static_mono}) -### -###if test "x$enable_static" = "xno"; then -### set(with_static_mono no) -###fi -### -###if test "x$platform_win32" = "xyes"; then -### # Boehm GC requires the runtime to be in its own dll -### set(with_static_mono no) -###fi -### -if(with_static_mono) - set(STATIC_MONO yes) -endif() -set(enable_mcs_build yes) -###AC_ARG_ENABLE(mcs-build, [ --disable-mcs-build disable the build of the mcs directory], set(try_mcs_build $enableval, enable_mcs_build=yes)) -### -###set(xen_opt, [ --with-set(xen_opt yes,no Enable Xen-specific behaviour (defaults to yes)],[],[with_xen_opt=yes])) -###if test "x$with_xen_opt" = "xyes"; then -### ac_define(MONO_XEN_OPT, 1, [Xen-specific behaviour]) -### set(ORIG_CFLAGS $CFLAGS) -### set(CFLAGS "$CFLAGS -mno-tls-direct-seg-refs") -### ac_msg_checking(for -mno-tls-direct-seg-refs option to gcc) -### AC_TRY_COMPILE([], [ -### void main () { } -### ], [ -### ac_msg_result(yes) -### # Pass it to libgc as well -### set(CFLAGS_FOR_LIBGC "$CFLAGS_FOR_LIBGC -mno-tls-direct-seg-refs") -### ], [ -### ac_msg_result(no) -### set(CFLAGS $ORIG_CFLAGS) -### ]) -###fi - -set (quiet-build yes CACHE BOOL "Enable quiet runtime build (on by default)") - -set(DISABLED_FEATURES none) - -###AC_ARG_ENABLE(minimal, [ --enable-set(minimal LIST drop support for LIST subsystems.) -### LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug, -### reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd.], -###[ -### for feature in `echo "$enable_minimal" | sed -e "s/,/ /g"`; do -### eval "mono_feature_disable_$set(feature 'yes'") -### AC_MSG_NOTICE([Disabled support for feature: $feature]) -### done -### set(DISABLED_FEATURES $enable_minimal) -### set(disabled "Disabled: $enable_minimal") -###],[]) -### -ac_define_unquoted(DISABLED_FEATURES "${DISABLED_FEATURES}" "String of disabled features") -### -###if test "x$mono_feature_disable_aot" = "xyes"; then -### AC_DEFINE(DISABLE_AOT_COMPILER, 1, [Disable AOT Compiler]) -### AC_MSG_NOTICE([Disabled AOT compiler]) -###fi -### -###if test "x$mono_feature_disable_profiler" = "xyes"; then -### ac_define(DISABLE_PROFILER, 1, [Disable default profiler support]) -###fi -###AM_CONDITIONAL(DISABLE_PROFILER, test x$mono_feature_disable_profiler = xyes) -### -###if test "x$mono_feature_disable_decimal" = "xyes"; then -### ac_define(DISABLE_DECIMAL, 1, [Disable System.Decimal support]) -###fi -### -###if test "x$mono_feature_disable_pinvoke" = "xyes"; then -### ac_define(DISABLE_PINVOKE, 1, [Disable P/Invoke support]) -###fi -### -###if test "x$mono_feature_disable_debug" = "xyes"; then -### ac_define(DISABLE_DEBUG, 1, [Disable runtime debugging support]) -###fi -### -###if test "x$mono_feature_disable_reflection_emit" = "xyes"; then -### ac_define(DISABLE_REFLECTION_EMIT, 1, [Disable reflection emit support]) -### set(mono_feature_disable_reflection_emit_save yes) -###fi -### -###if test "x$mono_feature_disable_reflection_emit_save" = "xyes"; then -### ac_define(DISABLE_REFLECTION_EMIT_SAVE, 1, [Disable assembly saving support in reflection emit]) -###fi -### -###if test "x$mono_feature_disable_large_code" = "xyes"; then -### ac_define(DISABLE_LARGE_CODE, 1, [Disable support for huge assemblies]) -###fi -### -###if test "x$mono_feature_disable_logging" = "xyes"; then -### ac_define(DISABLE_LOGGING, 1, [Disable support debug logging]) -###fi -### -###if test "x$mono_feature_disable_com" = "xyes"; then -### ac_define(DISABLE_COM, 1, [Disable COM support]) -###fi -### -###if test "x$mono_feature_disable_ssa" = "xyes"; then -### ac_define(DISABLE_SSA, 1, [Disable advanced SSA JIT optimizations]) -###fi -### -###if test "x$mono_feature_disable_generics" = "xyes"; then -### ac_define(DISABLE_GENERICS, 1, [Disable generics support]) -###fi -### -###if test "x$mono_feature_disable_attach" = "xyes"; then -### ac_define(DISABLE_ATTACH, 1, [Disable agent attach support]) -###fi -### -###if test "x$mono_feature_disable_jit" = "xyes"; then -### ac_define(DISABLE_JIT, 1, [Disable the JIT, only full-aot mode will be supported by the runtime.]) -###fi -### -###AM_CONDITIONAL(DISABLE_JIT, test x$mono_feature_disable_jit = xyes) -### -###if test "x$mono_feature_disable_simd" = "xyes"; then -### ac_define(DISABLE_SIMD, 1, [Disable SIMD intrinsics related optimizations.]) -###fi -### -###ac_msg_checking(for visibility __attribute__) -###AC_TRY_COMPILE([], [ -### void __attribute__ ((visibility ("hidden"))) doit (void) {} -### void main () { doit (); } -###], [ -### set(have_visibility_hidden yes) -### ac_msg_result(yes) -###], [ -### set(have_visibility_hidden no) -### ac_msg_result(no) -###]) -### - -# -# libgc checks -# - -set(gc_headers no) -set(gc included) -set(use_included_gc no) -set(libgc_configure_args) -set(gc_default included) - -set(gc ${gc_default} CACHE STRING "The GC library to use (defaults to included)") -set(with_gc ${gc}) - -# FIXME: -set(enable_parallel_mark yes) -###AC_ARG_ENABLE(parallel-mark, [ --enable-parallel-mark Enables GC Parallel Marking], set(enable_parallel_mark $enableval, enable_parallel_mark=$parallel_mark)) -###if test x$enable_parallel_mark = xyes; then -### set(libgc_configure_args "$libgc_configure_args --enable-parallel-mark") -###fi -### -set(LIBGC_CFLAGS ) -set(LIBGC_LIBS ) -set(LIBGC_STATIC_LIBS ) -set(libgc_dir ) - -if (gc STREQUAL included) - set(found_boehm yes) - set(gc_headers yes) - set(use_included_gc yes) - set(libgc_dir libgc) - - set(LIBGC_CFLAGS '-I${top_srcdir}/libgc/include') - set(LIBGC_LIBS '${top_builddir}/libgc/libmonogc.la') - set(LIBGC_STATIC_LIBS '${top_builddir}/libgc/libmonogc-static.la') - - ac_define(HAVE_BOEHM_GC 1 "Have Boehm GC") -### AC_SUBST(HAVE_BOEHM_GC) - - ac_define(HAVE_GC_H 1 "Have gc.h") - ac_define(USE_INCLUDED_LIBGC 1 "Use included libgc") - - # The included libgc contains GCJ support - ac_define(HAVE_GC_GCJ_MALLOC 1 "Have GC_gcj_malloc") - ac_define(HAVE_GC_ENABLE 1 "Have GC_enable") - if (enable_parallel_mark STREQUAL yes) - ac_define_unquoted(USED_GC_NAME "Included Boehm (with typed GC and Parallel Mark)" "GC description") - else() - ac_define_unquoted(USED_GC_NAME "Included Boehm (with typed GC)" "GC description") - endif() -endif() - -###case "x$gc" in -### xboehm|xbohem|xyes) -### ac_check_headers(gc.h gc/gc.h, set(gc_headers yes)) -### AC_CHECK_LIB(gc, GC_malloc, set(found_boehm "yes",,$libdl)) -### -### if test "x$found_boehm" != "xyes"; then -### ac_msg_error("GC requested but libgc not found! Install libgc or run configure with --with-set(gc none.")) -### fi -### if test "x$gc_headers" != "xyes"; then -### ac_msg_error("GC requested but header files not found! You may need to install them by hand.") -### fi -### -### ac_define(HAVE_BOEHM_GC, 1, [Have Boehm GC]) -### AC_SUBST(HAVE_BOEHM_GC) -### set(LIBGC_LIBS "-lgc $libdl") -### set(LIBGC_STATIC_LIBS "$LIBGC_LIBS") -### -### # ac_check_funcs does not work for some reason... -### AC_CHECK_LIB(gc, GC_gcj_malloc, set(found_gcj_malloc "yes",,$libdl)) -### if test "x$found_gcj_malloc" = "xyes"; then -### ac_define(HAVE_GC_GCJ_MALLOC, 1, [Have GC_gcj_malloc]) -### ac_define_unquoted(USED_GC_NAME, "System Boehm (with typed GC)", [GC description]) -### else -### ac_define_unquoted(USED_GC_NAME, "System Boehm (no typed GC)", [GC description]) -### fi -### AC_CHECK_LIB(gc, GC_enable, set(found_gc_enable "yes",,$libdl)) -### if test "x$found_gc_enable" = "xyes"; then -### ac_define(HAVE_GC_ENABLE, 1, [Have 'GC_enable']) -### fi -### ;; -### -### xincluded) -### set(found_boehm yes) -### set(gc_headers yes) -### set(use_included_gc yes) -### set(libgc_dir libgc) -### -### set(LIBGC_CFLAGS '-I$(top_srcdir)/libgc/include') -### set(LIBGC_LIBS '$(top_builddir)/libgc/libmonogc.la') -### set(LIBGC_STATIC_LIBS '$(top_builddir)/libgc/libmonogc-static.la') -### -### ac_define(HAVE_BOEHM_GC, 1, [Have Boehm GC]) -### AC_SUBST(HAVE_BOEHM_GC) -### -### ac_define(HAVE_GC_H, 1, [Have gc.h]) -### ac_define(USE_INCLUDED_LIBGC, 1, [Use included libgc]) -### -### # The included libgc contains GCJ support -### ac_define(HAVE_GC_GCJ_MALLOC, 1, [Have GC_gcj_malloc]) -### ac_define(HAVE_GC_ENABLE, 1, [Have GC_enable]) -### if test x$enable_parallel_mark = xyes; then -### ac_define_unquoted(USED_GC_NAME, "Included Boehm (with typed GC and Parallel Mark)", [GC description]) -### else -### ac_define_unquoted(USED_GC_NAME, "Included Boehm (with typed GC)", [GC description]) -### fi -### ;; -### -### xsgen) -### set(found_boehm no) -### set(gc_headers no) -### set(use_included_gc no) -### ac_define(HAVE_SGEN_GC,1,[Using the simple generational GC.]) -### ac_define(HAVE_MOVING_COLLECTOR,1,[The GC can move objects.]) -### ac_define(HAVE_WRITE_BARRIERS,1,[The GC needs write barriers.]) -### ac_define_unquoted(USED_GC_NAME, "Simple generational", [GC description]) -### ;; -### -### xnone) -### AC_MSG_WARN("Compiling mono without GC.") -### ac_define_unquoted(USED_GC_NAME, "none", [GC description]) -### ac_define(HAVE_NULL_GC,1,[No GC support.]) -### ;; -### *) -### ac_msg_error([Invalid argument to --with-gc.]) -### ;; -###esac -### -###set(large-heap, [ --with-large-set(heap yes,no Enable support for GC heaps larger than 3GB (defaults to no)], [large_heap=$withval], [large_heap=no])) -###if test "x$large_heap" = "xyes"; then -### echo "FOO" -### set(CPPFLAGS "$CPPFLAGS -DLARGE_CONFIG") -###fi -### -###AM_CONDITIONAL(INCLUDED_LIBGC, test x$use_included_gc = xyes) -###AC_SUBST(LIBGC_CFLAGS) -###AC_SUBST(LIBGC_LIBS) -###AC_SUBST(LIBGC_STATIC_LIBS) -###AC_SUBST(libgc_dir) -### -# -# End of libgc checks -# - -include(CheckFunctionExists) -include(CheckLibraryExists) - -if(platform_win32 STREQUAL no) - -### - # hires monotonic clock support -### AC_SEARCH_LIBS(clock_gettime, rt) - - check_function_exists (dlopen dlopen_found) - if (dlopen_found) - set(DL_LIB "") - else() - check_library_exists (-ldl dlopen "" libdl_found) - if (libdl_found) - set(DL_LIB "-ldl") - else() - set(dl_support no) - endif() - endif() - - if (dl_support STREQUAL no) - # FIXME: - ### AC_MSG_WARN([No dynamic loading support available]) - else() - set(LIBS ${LIBS} ${DL_LIB}) - ac_define(HAVE_DL_LOADER 1 "dlopen-based dynamic loader available") - -### # from glib's configure.in -### AC_CACHE_CHECK([for preceeding underscore in symbols], -### mono_cv_uscore,[ -### AC_TRY_RUN([#include -### int mono_underscore_test (void) { return 42; } -### int main() { -### void *f1 = (void*)0, *f2 = (void*)0, *handle; -### handle = dlopen ((void*)0, 0); -### if (handle) { -### f1 = dlsym (handle, "mono_underscore_test"); -### f2 = dlsym (handle, "_mono_underscore_test"); -### } return (!f2 || f1); -### }], -### [set(mono_cv_uscore yes],) -### [set(mono_cv_uscore no],) -### []) -### ]) -### if test "x$mono_cv_uscore" = "xyes"; then -### set(MONO_DL_NEED_USCORE 1) -### else -### set(MONO_DL_NEED_USCORE 0) -### fi -### AC_SUBST(MONO_DL_NEED_USCORE) -### AC_CHECK_FUNC(dlerror) - endif() - - # ****************************************************************** - # *** Checks for the IKVM JNI interface library *** - # ****************************************************************** - set(ikvm-native yes CACHE BOOL "Build the IKVM JNI interface library (defaults to yes)") - set(with_ikvm_native ${ikvm-native}) - set(ikvm_native_dir ) - if(with_ikvm_native) - set(ikvm_native_dir ikvm-native) - set(jdk_headers_found "IKVM Native") - endif() - - ac_check_headers(execinfo.h) - - ac_check_funcs(getgrgid_r) - ac_check_funcs(getgrnam_r) - ac_check_funcs(getpwnam_r) - ac_check_funcs(getpwuid_r) - ac_check_funcs(getresuid) - ac_check_funcs(setresuid) - ac_check_funcs(kqueue) - ac_check_funcs(backtrace_symbols) - ac_check_funcs(mkstemp) - ac_check_funcs(mmap) - ac_check_funcs(madvise) - ac_check_funcs(getrusage) - ac_check_funcs(getpriority) - ac_check_funcs(setpriority) - - ac_check_funcs(sched_setaffinity) - - # ****************************************************************** - # *** Check for large file support *** - # *** (If we were using autoconf 2.50 we'd use AC_SYS_LARGEFILE) *** - # ****************************************************************** -### - # Check that off_t can represent 2**63 - 1 correctly, working around - # potential compiler bugs. Defines LARGE_FILE_SUPPORT, adds $1 to - # CPPFLAGS and sets $large_offt to yes if the test succeeds -### set(large_offt no) -### AC_DEFUN([LARGE_FILES], [ -### set(large_CPPFLAGS $CPPFLAGS) -### set(CPPFLAGS "$CPPFLAGS $1") -### AC_TRY_RUN([ -### #include -### -### #define BIG_OFF_T (((off_t)1<<62)-1+((off_t)1<<62)) -### -### int main(void) { -### int set(big_off_t ((BIG_OFF_T%2147483629==721) &&) -### (BIG_OFF_T%set(2147483647 =1));) -### if(big_off_t) { -### exit(0); -### } else { -### exit(1); -### } -### } -### ], [ -### ac_msg_result(ok) -### ac_define(HAVE_LARGE_FILE_SUPPORT, 1, [Have large file support]) -### set(large_CPPFLAGS "$large_CPPFLAGS $1") -### set(large_offt yes) -### ], [ -### ac_msg_result(no) -### ], "") -### set(CPPFLAGS $large_CPPFLAGS) -### ]) -### -### ac_msg_checking(if off_t is 64 bits wide) -### LARGE_FILES("") -### if test $large_offt = no; then -### ac_msg_checking(if set(_FILE_OFFSET_BITS 64 gives 64 bit off_t)) -### LARGE_FILES("-set(D_FILE_OFFSET_BITS 64")) -### fi -### if test $large_offt = no; then -### AC_MSG_WARN([No 64 bit file size support available]) -### fi -### - # ***************************** - # *** Checks for libsocket *** - # ***************************** -### AC_CHECK_LIB(socket, socket, set(LIBS "$LIBS -lsocket")) -### - # ******************************* - # *** Checks for MSG_NOSIGNAL *** - # ******************************* -### ac_msg_checking(for MSG_NOSIGNAL) -### AC_TRY_COMPILE([#include ], [ -### int f = MSG_NOSIGNAL; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_MSG_NOSIGNAL, 1, [Have MSG_NOSIGNAL]) -### ], [ -### # We'll have to use signals -### ac_msg_result(no) -### ]) -### - # ***************************** - # *** Checks for SOL_IP *** - # ***************************** -### ac_msg_checking(for SOL_IP) -### AC_TRY_COMPILE([#include ], [ -### int level = SOL_IP; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_SOL_IP, 1, [Have SOL_IP]) -### ], [ -### # We'll have to use getprotobyname -### ac_msg_result(no) -### ]) -### - # ***************************** - # *** Checks for SOL_IPV6 *** - # ***************************** -### ac_msg_checking(for SOL_IPV6) -### AC_TRY_COMPILE([#include ], [ -### int level = SOL_IPV6; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_SOL_IPV6, 1, [Have SOL_IPV6]) -### ], [ -### # We'll have to use getprotobyname -### ac_msg_result(no) -### ]) -### - # ***************************** - # *** Checks for SOL_TCP *** - # ***************************** -### ac_msg_checking(for SOL_TCP) -### AC_TRY_COMPILE([#include ], [ -### int level = SOL_TCP; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_SOL_TCP, 1, [Have SOL_TCP]) -### ], [ -### # We'll have to use getprotobyname -### ac_msg_result(no) -### ]) -### - # ***************************** - # *** Checks for IP_PKTINFO *** - # ***************************** -### ac_msg_checking(for IP_PKTINFO) -### AC_TRY_COMPILE([#include ], [ -### int level = IP_PKTINFO; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_IP_PKTINFO, 1, [Have IP_PKTINFO]) -### ], [ -### ac_msg_result(no) -### ]) -### - # ***************************** - # *** Checks for IPV6_PKTINFO *** - # ***************************** -### ac_msg_checking(for IPV6_PKTINFO) -### AC_TRY_COMPILE([#include ], [ -### int level = IPV6_PKTINFO; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_IPV6_PKTINFO, 1, [Have IPV6_PKTINFO]) -### ], [ -### ac_msg_result(no) -### ]) -### - # ********************************** - # *** Checks for IP_DONTFRAGMENT *** - # ********************************** -### ac_msg_checking(for IP_DONTFRAGMENT) -### AC_TRY_COMPILE([#include ], [ -### int level = IP_DONTFRAGMENT; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_IP_DONTFRAGMENT, 1, [Have IP_DONTFRAGMENT]) -### ], [ -### ac_msg_result(no) -### ]) -### - # ********************************** - # *** Checks for IP_MTU_DISCOVER *** - # ********************************** -### ac_msg_checking(for IP_MTU_DISCOVER) -### AC_TRY_COMPILE([#include ], [ -### int level = IP_MTU_DISCOVER; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_IP_MTU_DISCOVER, 1, [Have IP_MTU_DISCOVER]) -### ], [ -### ac_msg_result(no) -### ]) -### -### # ********************************* - # *** Check for struct ip_mreqn *** - # ********************************* -### ac_msg_checking(for struct ip_mreqn) -### AC_TRY_COMPILE([#include ], [ -### struct ip_mreqn mreq; -### mreq.imr_address.s_addr = 0; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_STRUCT_IP_MREQN, 1, [Have struct ip_mreqn]) -### ], [ -### # We'll just have to try and use struct ip_mreq -### ac_msg_result(no) -### ac_msg_checking(for struct ip_mreq) -### AC_TRY_COMPILE([#include ], [ -### struct ip_mreq mreq; -### mreq.imr_interface.s_addr = 0; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_STRUCT_IP_MREQ, 1, [Have struct ip_mreq]) -### ], [ -### # No multicast support -### ac_msg_result(no) -### ]) -### ]) -### - # ********************************** - # *** Check for gethostbyname2_r *** - # ********************************** -### ac_msg_checking(for gethostbyname2_r) -### AC_TRY_LINK([#include ], [ -### gethostbyname2_r(NULL,0,NULL,NULL,0,NULL,NULL); -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_GETHOSTBYNAME2_R, 1, [Have gethostbyname2_r]) -### ], [ -### ac_msg_result(no) -### ]) -### - # ***************************** - # *** Checks for libnsl *** - # ***************************** -### AC_CHECK_FUNC(gethostbyaddr, , AC_CHECK_LIB(nsl, gethostbyaddr, set(LIBS "$LIBS -lnsl"))) - -ac_check_funcs(inet_pton inet_aton) - -# *********************************************** -# *** Checks for size of sockaddr_un.sun_path *** -# *********************************************** -# FIXME: cache -ac_msg_checking("size of sockaddr_un.sun_path") - -FILE(WRITE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/conftest.c" -" - #include - #include - #include - - int main(void) { - struct sockaddr_un sock_un; - printf(\"%d\\n\", sizeof(sock_un.sun_path)); - exit(0); - } -") - -TRY_RUN(run_res run_compiled - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/conftest.c - RUN_OUTPUT_VARIABLE output) - -set(mono_cv_sizeof_sunpath 0) -if(run_compiled) - if (run_res EQUAL 0) - string(REGEX MATCH "[0-9]+" mono_cv_sizeof_sunpath ${output}) - endif() -endif() - -ac_msg_result(${mono_cv_sizeof_sunpath}) -ac_define(MONO_SIZEOF_SUNPATH ${mono_cv_sizeof_sunpath} "Sizeof sock_un.sun_path") -### - # ************************************* - # *** Checks for zero length arrays *** - # ************************************* -### ac_msg_checking(whether $CC supports zero length arrays) -### AC_TRY_COMPILE([ -### struct s { -### int length; -### char data [0]; -### }; -### ], [], [ -### ac_msg_result(yes) -### ac_define_unquoted(MONO_ZERO_ARRAY_LENGTH, 0, [Length of zero length arrays]) -### ], [ -### ac_msg_result(no) -### ac_define_unquoted(MONO_ZERO_ARRAY_LENGTH, 1, [Length of zero length arrays]) -### ]) -### - # ***************************** - # *** Checks for libxnet *** - # ***************************** -### case "${host}" in -### *solaris* ) -### ac_msg_checking(for Solaris XPG4 support) -### if test -f /usr/lib/libxnet.so; then -### set(CPPFLAGS "$CPPFLAGS -D_XOPEN_SOURCE=500") -### set(CPPFLAGS "$CPPFLAGS -D__EXTENSIONS__") -### set(CPPFLAGS "$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED=1") -### set(LIBS "$LIBS -lxnet") -### ac_msg_result(yes) -### else -### ac_msg_result(no) -### fi -### -### if test "$GCC" = "yes"; then -### set(CFLAGS "$CFLAGS -Wno-char-subscripts") -### fi -### ;; -### esac -### - # ***************************** - # *** Checks for libpthread *** - # ***************************** -# on FreeBSD -STABLE, the pthreads functions all reside in libc_r -# and libpthread does not exist -# -### case "${host}" in -### *-*-*freebsd*) -### AC_CHECK_LIB(pthread, main, set(LIBS "$LIBS -pthread")) -### ;; -### *) -### AC_CHECK_LIB(pthread, main, set(LIBS "$LIBS -lpthread")) -### ;; -### esac -ac_check_headers(pthread.h) -### ac_check_funcs(pthread_mutex_timedlock) -### ac_check_funcs(pthread_getattr_np pthread_attr_get_np) -### ac_msg_checking(for PTHREAD_MUTEX_RECURSIVE) -### AC_TRY_COMPILE([ #include ], [ -### pthread_mutexattr_t attr; -### pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -### ], [ -### ac_msg_result(ok) -### ], [ -### ac_msg_result(no) -### AC_MSG_WARN(Using mono_mutex_t for recursive mutexes) -### ac_define(USE_MONO_MUTEX, 1, [Use mono_mutex_t]) -### ]) -### ac_check_funcs(pthread_attr_setstacksize) -### ac_check_funcs(pthread_attr_getstack) -### ac_check_funcs(pthread_get_stacksize_np pthread_get_stackaddr_np) -### - # *********************************** - # *** Checks for working __thread *** - # *********************************** -### ac_msg_checking(for working __thread) -### if test "x$with_tls" != "x__thread"; then -### ac_msg_result(disabled) -### else -### AC_TRY_RUN([ -### #include -### __thread int i; -### static int res1, res2; -### -### void thread_main (void *arg) -### { -### i = arg; -### sleep (1); -### if (arg == 1) -### res1 = (i == arg); -### else -### res2 = (i == arg); -### } -### -### int main () { -### pthread_t t1, t2; -### -### i = 5; -### -### pthread_create (&t1, NULL, thread_main, 1); -### pthread_create (&t2, NULL, thread_main, 2); -### -### pthread_join (t1, NULL); -### pthread_join (t2, NULL); -### -### return !(res1 + res2 == 2); -### } -### ], [ -### ac_msg_result(yes) -### ], [ -### ac_msg_result(no) -### set(with_tls pthread) -### ]) -### fi -### - # ************************************** - # *** Checks for working sigaltstack *** - # ************************************** -### ac_msg_checking(for working sigaltstack) -### if test "x$with_sigaltstack" != "xyes"; then -### ac_msg_result(disabled) -### else -### AC_TRY_RUN([ -### #include -### #include -### #include -### #include -### #include -### #include -### #if defined(__FreeBSD__) || defined(__NetBSD__) -### #define SA_STACK SA_ONSTACK -### #endif -### static void -### sigsegv_signal_handler (int _dummy, siginfo_t *info, void *context) -### { -### exit (0); -### } -### -### static void * -### loop (void *ignored) -### { -### char *ptr = NULL; -### -### *ptr = 0; -### return NULL; -### } -### -### static void -### child () -### { -### struct sigaction sa; -### struct sigaltstack sas; -### pthread_t id; -### pthread_attr_t attr; -### -### sa.sa_sigaction = sigsegv_signal_handler; -### sigemptyset (&sa.sa_mask); -### sa.sa_flags = SA_SIGINFO | SA_ONSTACK; -### if (sigaction (SIGSEGV, &sa, NULL) == -1) { -### perror ("sigaction"); -### return; -### } -### -### sas.ss_sp = malloc (SIGSTKSZ); -### sas.ss_size = SIGSTKSZ; -### sas.ss_flags = 0; -### if (sigaltstack (&sas, NULL) == -1) { -### perror ("sigaltstack"); -### return; -### } -### -### pthread_attr_init (&attr); -### if (pthread_create(&id, &attr, loop, &attr) != 0) { -### printf ("pthread_create\n"); -### return; -### } -### -### sleep (100); -### } -### -### int -### main () -### { -### pid_t son; -### int status; -### int i; -### -### son = fork (); -### if (son == -1) { -### return 1; -### } -### -### if (son == 0) { -### child (); -### return 0; -### } -### -### for (i = 0; i < 3; ++i) { -### sleep (1); -### waitpid (son, &status, WNOHANG); -### if (WIFEXITED (status) && WEXITSTATUS (status) == 0) -### return 0; -### } -### -### kill (son, SIGKILL); -### return 1; -### } -### -### ], [ -### ac_msg_result(yes) -### ac_define(HAVE_WORKING_SIGALTSTACK, 1, [Have a working sigaltstack]) -### ], [ -### set(with_sigaltstack no) -### ac_msg_result(no) -### ]) -### fi -### - # ******************************** - # *** Checks for semaphore lib *** - # ******************************** - # 'Real Time' functions on Solaris - # posix4 on Solaris 2.6 - # pthread (first!) on Linux -### AC_SEARCH_LIBS(sem_init, pthread rt posix4) - check_library_exists(pthread shm_open "" HAVE_SHM_OPEN1) - if(HAVE_SHM_OPEN1) - # FIXME: - else() - check_library_exists(rt shm_open "" HAVE_SHM_OPEN2) - if(HAVE_SHM_OPEN2) - set(LIBS ${LIBS} -lrt) - set(CMAKE_REQUIRED_LIBRARIES rt) - ac_check_funcs(shm_open) - set(CMAKE_REQUIRED_LIBRARIES) - else() - # FIXME: posix4 - endif() - endif() - - # ******************************** - # *** Checks for timezone stuff ** - # ******************************** -### AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff, -### AC_TRY_COMPILE([ -### #include -### ], [ -### struct tm tm; -### tm.tm_gmtoff = 1; -### ], set(ac_cv_struct_tm_gmtoff yes, ac_cv_struct_tm_gmtoff=no))) -### if test $ac_cv_struct_tm_gmtoff = yes; then -### ac_define(HAVE_TM_GMTOFF, 1, [Have tm_gmtoff]) -### else -### AC_CACHE_CHECK(for timezone variable, ac_cv_var_timezone, -### AC_TRY_COMPILE([ -### #include -### ], [ -### timezone = 1; -### ], set(ac_cv_var_timezone yes, ac_cv_var_timezone=no))) -### if test $ac_cv_var_timezone = yes; then -### ac_define(HAVE_TIMEZONE, 1, [Have timezone variable]) -### else -### AC_ERROR(unable to find a way to determine timezone) -### fi -### fi -### -# ********************************* -# *** Checks for math functions *** -# ********************************* -set(LIBS ${LIBS} -lm) -### if test "x$has_broken_apple_cpp" != "xyes"; then -### ac_check_funcs(finite, , ac_msg_checking(for finite in math.h) -### AC_TRY_LINK([#include ], -### [ finite(0.0); ], -### ac_define(HAVE_FINITE, 1, [Have finite]) ac_msg_result(yes), -### ac_msg_result(no))) -### fi -### ac_check_funcs(isfinite, , ac_msg_checking(for isfinite in math.h) -### AC_TRY_LINK([#include ], -### [ isfinite(0.0); ], -### ac_define(HAVE_ISFINITE, 1, [Have isfinite]) ac_msg_result(yes), -### ac_msg_result(no))) -### -# **************************************************************** -# *** Checks for working poll() (macosx defines it but doesn't *** -# *** have it in the library (duh)) *** -# **************************************************************** -### ac_check_funcs(poll) -### -# ************************* -# *** Check for signbit *** -# ************************* -### ac_msg_checking(for signbit) -### AC_TRY_LINK([#include ], [ -### int s = signbit(1.0); -### ], [ -### ac_msg_result(yes) -### ac_define(HAVE_SIGNBIT, 1, [Have signbit]) -### ], [ -### ac_msg_result(no) -### ]) -### -# ********************************** -# *** epoll *** -# ********************************** -ac_check_headers(sys/epoll.h) -set(haveepoll no) -### ac_check_funcs(epoll_ctl, [set(haveepoll yes], )) -### if test "x$haveepoll" = "xyes" -a "x$ac_cv_header_sys_epoll_h" = "xyes" ; then -### ac_define(HAVE_EPOLL, 1, [epoll supported]) -### fi -### -# ****************************** -# *** Checks for SIOCGIFCONF *** -# ****************************** -ac_check_headers(sys/ioctl.h) -ac_check_headers(net/if.h) -### ac_msg_checking(for ifreq) -### AC_TRY_COMPILE([ -### #include -### #include -### #include -### ], [ -### struct ifconf ifc; -### struct ifreq *ifr; -### void *x; -### ifc.ifc_len = 0; -### ifc.ifc_buf = NULL; -### x = (void *) &ifr->ifr_addr; -### ],[ -### ac_msg_result(yes) -### ac_define(HAVE_SIOCGIFCONF, 1, [Can get interface list]) -### ], [ -### ac_msg_result(no) -### ]) -# ********************************** -# *** Checks for sin_len *** -# ********************************** -### ac_msg_checking(for sockaddr_in.sin_len) -### AC_TRY_COMPILE([ -### #include -### ], [ -### struct sockaddr_in saddr; -### saddr.sin_len = sizeof (saddr); -### ],[ -### ac_msg_result(yes) -### ac_define(HAVE_SOCKADDR_IN_SIN_LEN, 1, [sockaddr_in has sin_len]) -### ], [ -### ac_msg_result(no) -### ]) -# ********************************** -# *** Checks for sin6_len *** -# ********************************** -### ac_msg_checking(for sockaddr_in6.sin6_len) -### AC_TRY_COMPILE([ -### #include -### ], [ -### struct sockaddr_in6 saddr6; -### saddr6.sin6_len = sizeof (saddr6); -### ],[ -### ac_msg_result(yes) -### ac_define(HAVE_SOCKADDR_IN6_SIN_LEN, 1, [sockaddr_in6 has sin6_len]) -### ], [ -### ac_msg_result(no) -### ]) -# ********************************** -# *** Checks for MonoPosixHelper *** -# ********************************** -ac_check_headers(checklist.h) -ac_check_headers(fstab.h) -ac_check_headers(attr/xattr.h) -ac_check_headers(sys/extattr.h) -ac_check_headers(sys/sendfile.h) -ac_check_headers(sys/statvfs.h) -ac_check_headers(sys/statfs.h) -ac_check_headers(sys/vfstab.h) -ac_check_headers(sys/xattr.h) -ac_check_headers(sys/mman.h) -ac_check_headers(sys/param.h) -ac_check_headers(sys/mount.h) -### ac_check_funcs(getdomainname) -### ac_check_funcs(setdomainname) -### ac_check_funcs(fgetgrent) -### ac_check_funcs(fgetpwent) -### ac_check_funcs(fgetpwent) -### ac_check_funcs(getfsstat) -### ac_check_funcs(lutimes) -### ac_check_funcs(mremap) -### ac_check_funcs(remap_file_pages) -### ac_check_funcs(posix_fadvise) -### ac_check_funcs(posix_fallocate) -### ac_check_funcs(posix_madvise) -### ac_check_funcs(vsnprintf) -### ac_check_funcs(sendfile) -### ac_check_funcs(sethostid) -### ac_check_funcs(statfs) -### ac_check_funcs(fstatfs) -### ac_check_funcs(statvfs) -### ac_check_funcs(fstatvfs) -### ac_check_funcs(stime) -### ac_check_funcs(strerror_r) -### ac_check_funcs(ttyname_r) -ac_check_sizeof(size_t) -### AC_CHECK_TYPES([blksize_t], [ac_define(HAVE_BLKSIZE_T)], , -### [#include -### #include -### #include ]) -### AC_CHECK_TYPES([blkcnt_t], [ac_define(HAVE_BLKCNT_T)], , -### [#include -### #include -### #include ]) -### AC_CHECK_TYPES([suseconds_t], [ac_define(HAVE_SUSECONDS_T)], , -### [#include ]) -### AC_CHECK_TYPES([struct flock], [ac_define(HAVE_STRUCT_FLOCK)], , -### [#include -### #include ]) -### AC_CHECK_TYPES([struct pollfd], [ac_define(HAVE_STRUCT_POLLFD)], , -### [#include ]) -### AC_CHECK_TYPES([struct stat], [ac_define(HAVE_STRUCT_STAT)], , -### [#include -### #include -### #include ]) -### AC_CHECK_TYPES([struct timespec], [ac_define(HAVE_STRUCT_TIMESPEC)], , -### [#include ]) -### AC_CHECK_TYPES([struct timeval], [ac_define(HAVE_STRUCT_TIMEVAL)], , -### [#include -### #include -### #include ]) -### AC_CHECK_TYPES([struct timezone], [ac_define(HAVE_STRUCT_TIMEZONE)], , -### [#include ]) -### AC_CHECK_TYPES([struct utimbuf], [ac_define(HAVE_STRUCT_UTIMBUF)], , -### [#include -### #include ]) -### AC_CHECK_MEMBERS( -### [struct dirent.d_off, struct dirent.d_reclen, struct dirent.d_type],,, -### [#include -### #include ]) -### -# Favour xattr through glibc, but use libattr if we have to -### AC_CHECK_FUNC(lsetxattr, , -### AC_CHECK_LIB(attr, lsetxattr, set(XATTR_LIB "-lattr",)) -### ) -### AC_SUBST(XATTR_LIB) -### -# kinfo_proc.kp_proc works on darwin but fails on other simil-bsds -### AC_CHECK_MEMBERS( -### [struct kinfo_proc.kp_proc],,, -### [#include -### #include -### #include -### ]) -### -# ********************************* -# *** Checks for Windows compilation *** -# ********************************* -ac_check_headers(sys/time.h) -ac_check_headers(sys/param.h) -ac_check_headers(dirent.h) - -# ********************************* -# *** Check for Console 2.0 I/O *** -# ********************************* -ac_check_headers(curses.h) -ac_check_headers(term.h) -### ac_check_headers([term.h], [], [], -### [#if HAVE_CURSES_H -### #include -### #endif -### ]) -ac_check_headers(termios.h) -### -# * This is provided in io-layer, but on windows it's only available -# * on xp+ -### ac_define(HAVE_GETPROCESSID, 1, [Define if GetProcessId is available]) -###else -### set(jdk_headers_found no) -### AC_CHECK_LIB(ws2_32, main, set(LIBS "$LIBS -lws2_32", AC_ERROR(bad mingw install?))) -### AC_CHECK_LIB(psapi, main, set(LIBS "$LIBS -lpsapi", AC_ERROR(bad mingw install?))) -### AC_CHECK_LIB(ole32, main, set(LIBS "$LIBS -lole32", AC_ERROR(bad mingw install?))) -### AC_CHECK_LIB(winmm, main, set(LIBS "$LIBS -lwinmm", AC_ERROR(bad mingw install?))) -### AC_CHECK_LIB(oleaut32, main, set(LIBS "$LIBS -loleaut32", AC_ERROR(bad mingw install?))) -### AC_CHECK_LIB(advapi32, main, set(LIBS "$LIBS -ladvapi32", AC_ERROR(bad mingw install?))) -### AC_CHECK_LIB(version, main, set(LIBS "$LIBS -lversion", AC_ERROR(bad mingw install?))) -### -# ********************************* -# *** Check for struct ip_mreqn *** -# ********************************* -### ac_msg_checking(for struct ip_mreqn) -### AC_TRY_COMPILE([#include ], [ -### struct ip_mreqn mreq; -### mreq.imr_address.s_addr = 0; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_STRUCT_IP_MREQN) -### ], [ -### # We'll just have to try and use struct ip_mreq -### ac_msg_result(no) -### ac_msg_checking(for struct ip_mreq) -### AC_TRY_COMPILE([#include ], [ -### struct ip_mreq mreq; -### mreq.imr_interface.s_addr = 0; -### ], [ -### # Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_STRUCT_IP_MREQ) -### ], [ -### # No multicast support -### ac_msg_result(no) -### ]) -### ]) -### ac_check_funcs(GetProcessId) -###fi -### -endif() - -# socklen_t check -ac_msg_checking("for socklen_t") -check_c_source_compiles(" -#include -#include -void main () { - socklen_t foo; -}" HAVE_SOCKLEN_T) -if(HAVE_SOCKLEN_T) - ac_define(HAVE_SOCKLEN_T 1 "Have socklen_t") - ac_msg_result(yes) -else() - ac_msg_result(no) -endif() - -###ac_msg_checking(for array element initalizer support) -###AC_TRY_COMPILE([#include ], [ -### const int array[] = {[1] = 2,}; -###], [ -# Yes, we have it... -### ac_msg_result(yes) -### ac_define(HAVE_ARRAY_ELEM_INIT,1,[Supports C99 array initialization]) -###], [ -# We'll have to use signals -### ac_msg_result(no) -###]) -### -ac_check_funcs(trunc) -if(NOT HAVE_TRUNC) - ac_msg_checking("for trunc in math.h") - # Simply calling trunc (0.0) is no good since gcc will optimize the call away - set(compiles) - check_c_source_compiles(" -#include -void main () { -static void *p = &trunc; -} -" compiles) - if (compiles) - ac_define(HAVE_TRUNC 1 "") - ac_msg_result(yes) - else() - ac_msg_result(no) - endif() -endif() - -###if test "x$ac_cv_truncl" != "xyes"; then -### AC_CHECK_LIB(sunmath, aintl, [ ac_define(HAVE_AINTL, 1, [Has the 'aintl' function]) set(LIBS "$LIBS -lsunmath"])) -###fi - -ac_check_funcs(round) -ac_check_funcs(rint) - -# **************************** -# *** Look for /dev/random *** -# **************************** - -###ac_msg_checking([if usage of random device is requested]) -###AC_ARG_ENABLE(dev-random, -###[ --disable-dev-random disable the use of the random device (enabled by default)], -###set(try_dev_random $enableval, try_dev_random=yes)) - -###ac_msg_result($try_dev_random) - -###case "{$target}" in -### *-openbsd*) -### set(NAME_DEV_RANDOM "/dev/srandom") -### ;; - -# Win32 does not have /dev/random, they have their own method... - -### *-*-mingw*|*-*-cygwin*) -### set(ac_cv_have_dev_random no) -### ;; - -# Everywhere else, it's /dev/random - -### *) -### set(NAME_DEV_RANDOM "/dev/random") -### ;; -###esac - -###ac_define_unquoted(NAME_DEV_RANDOM, "$NAME_DEV_RANDOM", [Name of /dev/random]) - -# Now check if the device actually exists - -###if test "x$try_dev_random" = "xyes"; then -### AC_CACHE_CHECK(for random device, ac_cv_have_dev_random, -### [if test -r "$NAME_DEV_RANDOM" ; then -### set(ac_cv_have_dev_random yes; else ac_cv_have_dev_random=no; fi])) -### if test "x$ac_cv_have_dev_random" = "xyes"; then -### ac_define(HAVE_CRYPT_RNG, 1, [Have /dev/random]) -### fi -###else -### ac_msg_checking(for random device) -### set(ac_cv_have_dev_random no) -### ac_msg_result(has been disabled) -###fi - -###if test "x$platform_win32" = "xyes"; then -### ac_define(HAVE_CRYPT_RNG) -###fi - -###if test "x$ac_cv_have_dev_random" = "xno" \ -### && test "x$platform_win32" = "xno"; then -### AC_MSG_WARN([[ -###*** -###*** A system-provided entropy source was not found on this system. -###*** Because of this, the System.Security.Cryptography random number generator -###*** will throw a NotImplemented exception. -###*** -###*** If you are seeing this message, and you know your system DOES have an -###*** entropy collection in place, please contact and -###*** provide information about the system and how to access the random device. -###*** -###*** Otherwise you can install either egd or prngd and set the environment -###*** variable MONO_EGD_SOCKET to point to the daemon's socket to use that. -###***]]) -###fi -### -###ac_msg_checking([if inter-process shared handles are requested]) -###AC_ARG_ENABLE(shared-handles, [ --disable-shared-handles disable inter-process shared handles], set(try_shared_handles $enableval, try_shared_handles=yes)) -###ac_msg_result($try_shared_handles) -###if test "x$try_shared_handles" != "xyes"; then -### ac_define(DISABLE_SHARED_HANDLES, 1, [Disable inter-process shared handles]) -### AC_SUBST(DISABLE_SHARED_HANDLES) -###fi - -###if test x$gc = xsgen; then -### if test x$with_tls != x__thread; then -### ac_msg_error([The SGEN garbage collector depends on a working __thread implementation, and either --with-set(thread pthread was passed to configure, or the configure test for __thread failed.])) -### fi -###fi - -###AC_ARG_ENABLE(nunit-tests, [ --enable-nunit-tests Run the nunit tests of the class library on 'make check']) -###AM_CONDITIONAL(ENABLE_NUNIT_TESTS, [test x$enable_nunit_tests = xyes]) - -ac_msg_checking("if big-arrays are to be enabled") -set(big-arrays no CACHE STRING "Enable the allocation and indexing of arrays greater than Int32.MaxValue]") -set(enable_big_arrays ${big-arrays}) -###if test "x$enable_big_arrays" = "xyes" ; then -### if test "x$ac_cv_sizeof_void_p" = "x8"; then -### ac_define(MONO_BIG_ARRAYS,1,[Enable the allocation and indexing of arrays greater than Int32.MaxValue]) -### else -### ac_msg_error([The allocation and indexing of arrays greater than Int32.MaxValue is not supported on this platform.]) -### fi -###fi -###ac_msg_result($enable_big_arrays) - -# ************** -# *** DTRACE *** -# ************** - -set(dtrace ${has_dtrace} CACHE BOOL "Enable DTrace probes") -set(enable_dtrace ${dtrace}) - -###if test "x$enable_dtrace" = "xyes"; then -### if test "x$has_dtrace" = "xno"; then -### ac_msg_error([DTrace probes are not supported on this platform.]) -### fi -### AC_PATH_PROG(DTRACE, [dtrace], [no], [$PATH:/usr/sbin]) -### if test "x$DTRACE" = "xno"; then -### ac_msg_result([dtrace utility not found, dtrace support disabled.]) -### set(enable_dtrace no) -### fi -###fi - -set(dtrace_g no) -###if test "x$enable_dtrace" = "xyes"; then -### ac_define(ENABLE_DTRACE, 1, [Enable DTrace probes]) -### set(DTRACEFLAGS ) -### if test "x$ac_cv_sizeof_void_p" = "x8"; then -### case "$host" in -### powerpc-*-darwin*) -### set(DTRACEFLAGS "-arch ppc64") -### ;; -### i*86-*-darwin*) -### set(DTRACEFLAGS "-arch x86_64") -### ;; -### *) -### set(DTRACEFLAGS -64) -### ;; -### esac -### else -### case "$host" in -### powerpc-*-darwin*) -### set(DTRACEFLAGS "-arch ppc") -### ;; -### i*86-*-darwin*) -### set(DTRACEFLAGS "-arch i386") -### ;; -### *) -### set(DTRACEFLAGS -32) -### ;; -### esac -### fi -### AC_SUBST(DTRACEFLAGS) -### case "$host" in -### *-*-solaris*) -### set(dtrace_g yes) -### ;; -### esac -### ac_check_headers([sys/sdt.h]) -###fi -###AM_CONDITIONAL(ENABLE_DTRACE, [test x$enable_dtrace = xyes]) -###AM_CONDITIONAL(DTRACE_G_REQUIRED, [test x$dtrace_g = xyes]) - -# ************** -# *** LLVM *** -# ************** - -set(llvm no CACHE BOOL "Enable the experimental LLVM back-end") -set(enable_llvm ${llvm}) - -###if test "x$enable_llvm" = "xyes"; then -### AC_PATH_PROG(LLVM_CONFIG, llvm-config, no) -### if test "x$LLVM_CONFIG" = "xno"; then -### ac_msg_error([llvm-config not found.]) -### fi - -### set(LLVM_CXXFLAGS `$LLVM_CONFIG --cflags`) -### set(LLVM_LDFLAGS `$LLVM_CONFIG --ldflags`) -### LLVM_LIBS=`$LLVM_CONFIG --libs core bitwriter jit x86codegen` -### set(LLVM_LIBS "$LLVM_LDFLAGS $LLVM_LIBS -lstdc++") - -### AC_SUBST(LLVM_CXXFLAGS) -### AC_SUBST(LLVM_LIBS) -### AC_SUBST(LLVM_LDFLAGS) -### ac_define(ENABLE_LLVM, 1, [Enable the LLVM back end]) -###fi - -if(enable_llvm) - set(ENABLE_LLVM yes) -endif() - -# -# Architecture-specific checks -# -set(TARGET "unknown") -set(ACCESS_UNALIGNED "yes") - -set(JIT_SUPPORTED no) -set(INTERP_SUPPORTED no) -set(LIBC "libc.so.6") -set(INTL "libc.so.6") -set(SQLITE "libsqlite.so.0") -set(SQLITE3 "libsqlite3.so.0") -set(X11 "libX11.so") - -set(sizeof_register "SIZEOF_VOID_P") - -set(jit_wanted false) -set(interp_wanted false) - -if(host MATCHES "(x86_64-.*-.*)|(amd64-.*-.*)") - set(TARGET AMD64) - set(arch_target amd64) - set(JIT_SUPPORTED yes) - set(jit_wanted true) -elseif(host MATCHES "arm.*-linux.*") - set(TARGET ARM) - set(arch_target arm) - set(ACCESS_UNALIGNED no) - set(JIT_SUPPORTED yes) - set(jit_wanted true) -elseif(host MATCHES "mips.*") - set(TARGET MIPS) - set(arch_target mips) - set(ACCESS_UNALIGNED no) - set(JIT_SUPPORTED yes) - set(jit_wanted true) -### ac_msg_checking(for mips n32) -### AC_TRY_COMPILE([], [ -### void main () { -### #if _MIPS_SIM != _ABIN32 -### #error Not mips n32 -### #endif -### } -### ],[ -### ac_msg_result(yes) -### set(sizeof_register 8) -### ],[ -### ac_msg_result(no) -### ]) -### ;; -else() - message(FATAL_ERROR "Host ${host} not yet supported by the cmake build.") -endif() - -# FIXME: Define the others as well -if (${TARGET} STREQUAL "X86") - ac_define(TARGET_X86 1 [...]) -elseif (${TARGET} STREQUAL "AMD64") - ac_define(TARGET_AMD64 1 [...]) -elseif (${TARGET} STREQUAL "ARM") - ac_define(TARGET_ARM 1 [...]) -endif() - -###case "$host" in -# mips-sgi-irix5.* | mips-sgi-irix6.*) -# set(TARGET MIPS;) -# set(ACCESS_UNALIGNED "no") -# ;; -### i*86-*-*) -### set(TARGET X86;) -### set(arch_target x86;) -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### case $host_os in -### solaris*) -### set(LIBC "libc.so") -### set(INTL "libintl.so") -### if test "x$ac_cv_sizeof_void_p" = "x8"; then -### set(TARGET AMD64) -### set(arch_target amd64) -### fi - -### # On solaris 10 x86, gcc prints a warning saying 'visibility attribute not supported on this configuration; ignored', but linking fails. A test case: -### # int astruct __attribute__ ((visibility ("hidden"))); -### # void foo () -### # { -### # void *p = &astruct; -### # } -### # gcc -fPIC --shared -o libfoo.so foo.c -### # yields: -### # 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 -### set(have_visibility_hidden no) - -### esac -### ;; -### ia64-*-*) -### set(TARGET IA64) -### set(arch_target ia64) -### set(ACCESS_UNALIGNED "no") -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### set(LIBC "libc.so.6.1") -### set(INTL "libc.so.6.1") -### AC_CHECK_LIB(unwind, _U_dyn_register, [], [ac_msg_error(library libunwind not found)]) -### set(libmono_ldflags "-lunwind") -### ;; -### sparc*-*-*) -### if test "x$ac_cv_sizeof_void_p" = "x8"; then -### set(TARGET SPARC64) -### else -### set(TARGET SPARC) -### fi -### set(arch_target sparc;) -### set(JIT_SUPPORTED yes) -### set(ACCESS_UNALIGNED "no") -### case $host_os in -### linux*) ;; -### *) -### set(LIBC "libc.so") -### set(INTL "libintl.so") -### esac -### set(jit_wanted true) -### if test x"$GCC" = xyes; then -### # We don't support v8 cpus -### set(CFLAGS "$CFLAGS -Wno-cast-align -mcpu=v9") -### fi -### 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 -### ;; -### alpha*-*-linux* | alpha*-*-osf*) -### set(TARGET ALPHA;) -### set(ACCESS_UNALIGNED "no") -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### set(arch_target alpha;) -### set(CFLAGS "$CFLAGS -mieee -O0") -### case $host_os in -### linux*) -### set(LIBC "libc.so.6.1") -### set(INTL "libc.so.6.1") -### esac -### ;; -### *-*-mingw*|*-*-cygwin*) -### # When this is enabled, it leads to very strange crashes at runtime (gcc-3.4.4) -### set(have_visibility_hidden no) -### set(INTL "intl") -### ;; -### hppa2.0w-hp-hpux11.00 | hppa64-hp-hpux11.00) -### set(TARGET HPPA;) -### set(arch_target hppa; ) -### set(LIBC "libc.sl") -### set(ACCESS_UNALIGNED "no") -### set(INTERP_SUPPORTED yes) -### set(interp_wanted true) -### ;; -### hppa*linux*) -### set(TARGET HPPA;) -### ac_define(MONO_ARCH_REGPARMS,1,[Architecture uses registers for Parameters]) -### set(arch_target hppa; ) -### set(ACCESS_UNALIGNED "no") -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### ;; -### macppc-*-openbsd* | powerpc*-*-linux* | powerpc-*-openbsd* | \ -### powerpc-*-sysv* | powerpc-*-darwin* | powerpc-*-netbsd* ) -### if test "x$ac_cv_sizeof_void_p" = "x8"; then -### set(TARGET POWERPC64;) -### set(CPPFLAGS "$CPPFLAGS -D__mono_ppc__ -D__mono_ppc64__") -### set(CFLAGS "$CFLAGS -mminimal-toc") -### else -### set(TARGET POWERPC;) -### set(CPPFLAGS "$CPPFLAGS -D__mono_ppc__") -### fi -### ac_define(MONO_ARCH_REGPARMS,1,[Architecture uses registers for Parameters]) -### set(arch_target ppc;) -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### ;; -### arm*-darwin*) -### set(TARGET ARM;) -### set(arch_target arm;) -### set(ACCESS_UNALIGNED "no") -### set(JIT_SUPPORTED yes) -### set(CPPFLAGS "$CPPFLAGS -DARM_FPU_NONE=1") -### set(jit_wanted true) -### ;; -### s390-*-linux*) -### set(TARGET S390;) -### ac_define(MONO_ARCH_REGPARMS,1,[Architecture uses registers for Parameters]) -### set(arch_target s390;) -### set(ACCESS_UNALIGNED "no") -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### # Required CFLAGS for s390[x]. USE_STRING_INLINES is automatic with gcc 4.1 -### set(CFLAGS "$CFLAGS -mbackchain -D__USE_STRING_INLINES") -### ;; -### s390x-*-linux*) -### set(TARGET S390x;) -### ac_define(MONO_ARCH_REGPARMS,1,[Architecture uses registers for Parameters]) -### set(arch_target s390x;) -### set(ACCESS_UNALIGNED "no") -### set(JIT_SUPPORTED yes) -### set(jit_wanted true) -### set(CFLAGS "$CFLAGS -mbackchain -D__USE_STRING_INLINES") -### ;; -###esac - -if (${sizeof_register} STREQUAL "4") - ac_define(SIZEOF_REGISTER 4 "size of machine integer registers") -elseif (${sizeof_register} STREQUAL "8") - ac_define(SIZEOF_REGISTER 8 "size of machine integer registers") -else() - ac_define(SIZEOF_REGISTER SIZEOF_VOID_P "size of machine integer registers") -endif() - -###if test "x$target_byte_order" = "xG_BIG_ENDIAN"; then -### AC_DEFINE(TARGET_BYTE_ORDER,G_BIG_ENDIAN,[byte order of target]) -###elif test "x$target_byte_order" = "xG_LITTLE_ENDIAN"; then -### AC_DEFINE(TARGET_BYTE_ORDER,G_LITTLE_ENDIAN,[byte order of target]) -###else -### AC_DEFINE(TARGET_BYTE_ORDER,G_BYTE_ORDER,[byte order of target]) -###fi - -###if (${have_visibility_hidden" = "xyes"; then -### ac_define(HAVE_VISIBILITY_HIDDEN, 1, [Support for the visibility ("hidden") attribute]) -###fi - -###set(jit, [ --with-set(jit yes,no If you want to build scripts that default to the JIT (defaults to no)],[) -### if test x$withval = xyes; then -### set(jit_wanted true) -### else -### set(jit_wanted false) -### fi -###]) - -###set(interp, [ --with-set(interp yes,no If you want to build scripts that default to the interpreter (defaults to no)],[) -### if test x$withval = xyes; then -### set(interp_wanted true) -### else -### set(interp_wanted false) -### fi -###]) - -set(USEJIT no) -if(JIT_SUPPORTED) - if (jit_wanted) - set(USEJIT yes) - set(jit_status "Building and using the JIT") - else() - if (interp_wanted) - set(jit_status "Building the JIT, defaulting to the interpreter") - else() - message(FATAL_ERROR "No JIT or interpreter support available or selected.") - endif() - endif() -else() - if (interp_wanted) - set(jit_status "interpreter") - else() - message(FATAL_ERROR "No JIT or interpreter support available or selected.") - endif() -endif() -set(USE_JIT ${USEJIT}) - -set(libsuffix ".so") - -###case "$host" in -### *-*-darwin*) -### set(libsuffix ".dylib") -### set(LIBC "libc.dylib") -### set(INTL "libintl.dylib") -### set(SQLITE "libsqlite.0.dylib") -### set(SQLITE3 "libsqlite3.0.dylib") -### set(X11 "libX11.dylib") -### ;; -### *-*-*netbsd*) -### set(LIBC "libc.so.12") -### set(INTL "libintl.so.0") -### ;; -### *-*-*freebsd*) -### set(LIBC "libc.so") -### set(INTL "libintl.so") -### ;; -### *-*-*openbsd*) -### set(LIBC "libc.so") -### set(INTL "libintl.so") -### ;; -### *-*-*linux*) -### AC_PATH_X -### ac_msg_checking(for the soname of libX11.so) -### for i in $x_libraries /usr/lib /usr/lib64; do -### for r in 4 5 6; do -### if test -f $i/libX11.so.$r; then -### set(X11 libX11.so.$r) -### ac_msg_result($X11) -### fi -### done -### done -### -### if (${X11" = "xlibX11.so"; then -### AC_MSG_WARN([Could not find X development libs. Do you have the -devel package installed? WinForms may not work...]); -### fi -### ;; -###esac - - -###AC_SUBST(libsuffix) - -ac_check_headers(valgrind/memcheck.h) -if(${TARGET} STREQUAL "AMD64" OR ${TARGET} STREQUAL "X86") - if(with_tls STREQUAL __thread) - # - # On some linux distributions, TLS works in executables, but linking - # against a shared library containing TLS fails with: - # undefined reference to `__tls_get_addr' - # -### rm -f conftest.c conftest.so conftest -### echo "static __thread int foo; void main () { foo = 5; }" > conftest.c -### $CC -fPIC --shared -o conftest.so conftest.c > /dev/null 2>&1 -### $CC -o conftest conftest.so > /dev/null 2>&1 -### if test ! -f conftest; then -### AC_MSG_WARN([Disabling usage of __thread.]); -### set(with_tls pthread) -### fi -### rm -f conftest.c conftest.so conftest - endif() -endif() - -set(mono_debugger_supported no) -if(${TARGET} STREQUAL "AMD64" OR ${TARGET} STREQUAL "X86") - if(use_included_gc) - if (host MATCHES ".*-.*-.*linux.*") - set(mono_debugger_supported yes) - endif() - if (host MATCHES ".*86-apple-darwin.*") - set(mono_debugger_supported yes) - endif() - endif() -endif() - -ac_msg_checking("if the Mono Debugger is supported on this platform") -if(mono_debugger_supported) - ac_define(MONO_DEBUGGER_SUPPORTED 1 "The Mono Debugger is supported on this platform") -endif() -ac_msg_result(${mono_debugger_supported}) -if(mono_debugger_supported) - set(MONO_DEBUGGER_SUPPORTED yes) -endif() - -if (with_tls STREQUAL "__thread") - ac_define(HAVE_KW_THREAD 1 "Have __thread keyword") - ac_define(USE_COMPILER_TLS 1 "Use __thread for TLS access") -# Pass the information to libgc -set(CPPFLAGS "${CPPFLAGS} -DUSE_COMPILER_TLS") -### ac_msg_checking(if the tls_model attribute is supported) -### AC_TRY_COMPILE([static __thread int foo __attribute__((tls_model("initial-exec")));], [ -### ], [ -### ac_msg_result(yes) -### ac_define(HAVE_TLS_MODEL_ATTR, 1, [tld_model available]) -### ], [ -### ac_msg_result(no) -### ]) -###fi - -endif() - -# ****************************************** -# *** Check to see what FPU is available *** -# ****************************************** -# FIXME: Don't do this if cross-compiling -if(${TARGET} STREQUAL "ARM") - ac_msg_checking("which FPU to use") - set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=softfp -mfpu=vfp") - set(compiles_fpu_vfp) - check_c_source_compiles(" -void main () { - __asm__ (\"faddd d7, d6, d7\"); -} -" compiles_fpu_vfp) - set(compiles_fpu_fpa) - set(cmake_required_flags) - check_c_source_compiles(" -void main () { - __asm__ (\"ldfd f0, [r0]\"); -} -" compiles_fpu_fpa) - if(compiles_fpu_vfp) - set(fpu VFP) - elseif(compiles_fpu_fpa) - set(fpu FPA) - else() - set(fpu NONE) - endif() - ac_msg_result(${fpu}) - set(CPPFLAGS "${CPPFLAGS} -DARM_FPU_${fpu}=1") - set(fpu) -endif() - -if(${TARGET} STREQUAL "unknown") - set(CPPFLAGS ${CPPFLAGS} -DNO_PORT) - ac_msg_warn("mono has not been ported to ${host}: some things may not work.") -endif() - -if(NOT ACCESS_UNALIGNED) - set(CPPFLAGS "${CPPFLAGS} -DNO_UNALIGNED_ACCESS") -endif() - -###case "x$gc" in -### xincluded) -### # Pass CPPFLAGS to libgc configure -### # We should use a separate variable for this to avoid passing useless and -### # potentially problematic defines to libgc (like -set(D_FILE_OFFSET_BITS 64)) -### # This should be executed late so we pick up the final version of CPPFLAGS -### # The problem with this approach, is that during a reconfigure, the main -### # configure scripts gets invoked with these arguments, so we use separate -### # variables understood by libgc's configure to pass CPPFLAGS and CFLAGS. -### set(LIBGC_CPPFLAGS $CPPFLAGS) -### if test x$TARGET = xSPARC -o x$TARGET = xSPARC64; then -### set(LIBGC_CPPFLAGS `echo $LIBGC_CPPFLAGS | sed -e 's/-D_FILE_OFFSET_BITS=64//g'`) -### fi -### set(ac_configure_args "$ac_configure_args --disable-embed-check --with-libgc-threads=$libgc_threads $libgc_configure_args \"CPPFLAGS_FOR_LIBGC=$LIBGC_CPPFLAGS\" \"CFLAGS_FOR_LIBGC=$CFLAGS_FOR_LIBGC\"") -### AC_CONFIG_SUBDIRS(libgc) -### ;; -###esac - -set(with_moonlight yes CACHE BOOL "If you want to build the Moonlight 2.1 assemblies (defaults to yes)") -set(with_profile4 no CACHE BOOL "If you want to install the 4.0 FX (defaults to no)") -set(with_monotouch no CACHE BOOL "If you want to build the raw MonoTouch 2.1 assemblies (defaults to no)") -set(with_oprofile no) -set(with_oprofile no CACHE STRING " or 'no' to disable oprofile support (defaults to no)") -if (NOT with_oprofile STREQUAL no) -### if test x$with_oprofile != xno; then -### set(oprofile_include $with_oprofile/include) -### if test ! -f $oprofile_include/opagent.h; then -### ac_msg_error([oprofile include file not found at $oprofile_include/opagent.h]) -### fi -### set(OPROFILE yes) -### set(OPROFILE_CFLAGS "-I$oprofile_include") -### set(OPROFILE_LIBS "-L$with_oprofile/lib/oprofile -lopagent") -### ac_define(HAVE_OPROFILE,1,[Have oprofile support]) -### fi -###]) - -endif() -set(MALLOC_MEMPOOLS no) -set(malloc_mempools no CACHE STRING "Use malloc for each single mempool allocation (only for runtime debugging, defaults to no)") -### if test x$with_malloc_mempools = xyes; then -### set(MALLOC_MEMPOOLS yes) -### ac_define(USE_MALLOC_FOR_MEMPOOLS,1,[Use malloc for each single mempool allocation]) -### fi -###]) - - -set(DISABLE_MCS_DOCS no) -set(mcs_docs yes CACHE STRING "If you want to build the documentation under mcs (defaults to yes)") -if(NOT mcs_docs) - set(DISABLE_MCS_DOCS yes) -endif() -if(with_oprofile) - set(HAVE_OPROFILE yes) -endif() -###AC_SUBST(OPROFILE_CFLAGS) -###AC_SUBST(OPROFILE_LIBS) - -set(libs_list) -foreach(lib ${LIBS}) - set(libs_list "${libs_list} ${lib}") -endforeach() -set(libmono_ldflags "${libmono_ldflags} ${libs_list}") - -if(PREVIEW) - set(INSTALL_2_0 yes) -endif() -if(MOONLIGHT) - set(INSTALL_2_1 yes) -endif() - -###AM_CONDITIONAL(INSTALL_2_1, [test "x$with_moonlight" = xyes]) -###AM_CONDITIONAL(INSTALL_4_0, [test "x$with_profile4" = xyes]) -###AM_CONDITIONAL(INSTALL_MONOTOUCH, [test "x$with_monotouch" = xyes]) - -###AM_CONDITIONAL(MIPS_GCC, test ${TARGET}${ac_cv_prog_gcc} = MIPSyes) -###AM_CONDITIONAL(MIPS_SGI, test ${TARGET}${ac_cv_prog_gcc} = MIPSno) -# Define a variable for the target -set(${TARGET} 1) - -if (interp_wanted) - set(INTERP_SUPPORTED yes) -endif() -if (gc STREQUAL "included") - set(INCLUDED_LIBGC yes) -endif() - -###AC_SUBST(LIBC) -###AC_SUBST(INTL) -###AC_SUBST(SQLITE) -###AC_SUBST(SQLITE3) -###AC_SUBST(X11) -ac_define_unquoted(ARCHITECTURE "${arch_target}" "The architecture this is running on") -###AC_SUBST(arch_target) -###AC_SUBST(CFLAGS) -###AC_SUBST(CPPFLAGS) -###AC_SUBST(LDFLAGS) - -set(mono_build_root ${CMAKE_BINARY_DIR}) - -if (USEJIT) - set(mono_runtime mono/mini/mono) -else() - set(mono_runtime mono/interpreter/mint) -endif() - -set(mono_cfg_root ${mono_build_root}/runtime) -if (platform_win32) -###if test x$platform_win32 = xyes; then -### if (${cross_compiling" = "xno"; then -### set(mono_cfg_dir `cygpath -w -a $mono_cfg_root`\\etc) -### else -### set(mono_cfg_dir `echo $mono_cfg_root | tr '/' '\\\'`\\etc) -### fi -else() - set(mono_cfg_dir ${mono_cfg_root}/etc) -endif() - -function(ac_config_files file) - configure_file("${file}.in" ${file} @ONLY) -endfunction() -ac_config_files("po/mcs/Makefile.in") - -ac_config_files("runtime/mono-wrapper") -ac_config_files("runtime/monodis-wrapper") -execute_process (COMMAND chmod a+x runtime/mono-wrapper runtime/monodis-wrapper) - -###AC_CONFIG_COMMANDS([runtime/etc/mono/1.0/machine.config], -###[ set(depth ../../../..) -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) set(reldir $srcdir ;;) -### .) set(reldir $depth ;;) -### *) set(reldir $depth/$srcdir ;;) -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/1.0 -### cd runtime/etc/mono/1.0 -### rm -f machine.config -### $LN_S $reldir/data/net_1_1/machine.config machine.config -### cd $depth -###],[set(LN_S '$LN_S'])) - -###AC_CONFIG_COMMANDS([runtime/etc/mono/2.0/machine.config], -###[ set(depth ../../../..) -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) set(reldir $srcdir ;;) -### .) set(reldir $depth ;;) -### *) set(reldir $depth/$srcdir ;;) -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/2.0 -### cd runtime/etc/mono/2.0 -### rm -f machine.config -### $LN_S $reldir/data/net_2_0/machine.config machine.config -### cd $depth -###],[set(LN_S '$LN_S'])) - -###AC_CONFIG_COMMANDS([runtime/etc/mono/2.0/web.config], -###[ set(depth ../../../..) -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) set(reldir $srcdir ;;) -### .) set(reldir $depth ;;) -### *) set(reldir $depth/$srcdir ;;) -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/2.0 -### cd runtime/etc/mono/2.0 -### rm -f web.config -### $LN_S $reldir/data/net_2_0/web.config web.config -### cd $depth -###],[set(LN_S '$LN_S'])) - -###AC_CONFIG_COMMANDS([runtime/etc/mono/browscap.ini], -###[ set(depth ../../..) -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) set(reldir $srcdir ;;) -### .) set(reldir $depth ;;) -### *) set(reldir $depth/$srcdir ;;) -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/ -### cd runtime/etc/mono/ -### rm -f browscap.ini -### $LN_S $reldir/data/browscap.ini browscap.ini -### cd $depth -###],[set(LN_S '$LN_S'])) - -###AC_CONFIG_COMMANDS([runtime/etc/mono/2.0/Browsers/Compat.browser], -###[ set(depth ../../../../..) -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) set(reldir $srcdir ;;) -### .) set(reldir $depth ;;) -### *) set(reldir $depth/$srcdir ;;) -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/2.0/Browsers/ -### cd runtime/etc/mono/2.0/Browsers -### rm -f Compat.browser -### $LN_S $reldir/data/net_2_0/Browsers/Compat.browser Compat.browser -### cd $depth -###],[set(LN_S '$LN_S'])) - - -###AC_CONFIG_COMMANDS([runtime/etc/mono/4.0/machine.config], -###[ depth=../../../.. -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) reldir=$srcdir ;; -### .) reldir=$depth ;; -### *) reldir=$depth/$srcdir ;; -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/4.0 -### cd runtime/etc/mono/4.0 -### rm -f machine.config -### $LN_S $reldir/data/net_4_0/machine.config machine.config -### cd $depth -###],[LN_S='$LN_S']) -### -###AC_CONFIG_COMMANDS([runtime/etc/mono/4.0/web.config], -###[ depth=../../../.. -### case $srcdir in -### [[\\/$]]* | ?:[[\\/]]* ) reldir=$srcdir ;; -### .) reldir=$depth ;; -### *) reldir=$depth/$srcdir ;; -### esac -### $ac_aux_dir/install-sh -d runtime/etc/mono/4.0 -### cd runtime/etc/mono/4.0 -### rm -f web.config -### $LN_S $reldir/data/net_4_0/web.config web.config -### cd $depth -###],[LN_S='$LN_S']) -### - -###if test x$enable_quiet_build = xyes; then -### AC_CONFIG_COMMANDS([quiet], [for i in `find mono libgc support -name Makefile.in | sed -e 's/Makefile.in/Makefile/g'`; do if test -f $i; then $srcdir/scripts/patch-quiet.sh $i; fi; done], [set(shell $SHELL])) -### AC_CONFIG_COMMANDS([quiet-libtool], [sed -e 's/$echo "copying selected/$show "copying selected/g' < libtool > libtool.tmp && mv libtool.tmp libtool && chmod a+x libtool; sed -e 's/$ECHO "copying selected/# "copying selected/g' < libtool > libtool.tmp && mv libtool.tmp libtool && chmod a+x libtool]) -###fi - -if("${prefix}" STREQUAL "") - set(prefix /usr/local) -endif() -if("${exec_prefix}" STREQUAL "") - set(exec_prefix "\${prefix}") - set(exec_prefix_full "${prefix}") -else() - set(exec_prefix_full "${exec_prefix}") -endif() - -# FIXME: Make these overridable -set(bindir "\${exec_prefix}/bin") -set(bindir_full "${exec_prefix_full}/bin") -set(sbindir "\${exec_prefix}/sbin") -set(libexecdir "\${exec_prefix}/libexec") -set(datarootdir "\${prefix}/share") -set(datadir "\${datarootdir}") -set(sysconfdir "\${prefix}/etc") -set(sharedstatedir "\${prefix}/com") -set(localstatedir "\${prefix}/var") -set(includedir "\${prefix}/include") -set(oldincludedir "/usr/include") -set(docdir "\${datarootdir}/doc/\${PACKAGE}") -set(infodir "\${datarootdir}/info") -set(htmldir "\${docdir}") -set(dvidir "\${docdir}") -set(pdfdir "\${docdir}") -set(psdir "\${docdir}") -set(libdir "\${exec_prefix}/lib") -set(localedir "\${datarootdir}/locale") -set(mandir "\${datarootdir}/man") - -autoheader("config.h" autoheader_vars) - -set(SUBDIRS po ${libgc_dir} ${eglib_dir} mono ${ikvm_native_dir} support data runtime scripts man samples web msvc docs) - -foreach(dir ${SUBDIRS}) - add_subdirectory(${dir}) -endforeach() - -# Implementation of AC_OUTPUT for cmake -function(ac_output outputs) - foreach (output ${ARGV}) - configure_file ("${output}.in" "${output}" @ONLY) - endforeach() -endfunction() - -ac_output( -mono-uninstalled.pc -scripts/mono-find-provides -scripts/mono-find-requires -mono/tests/tests-config -data/mint.pc -data/mono.pc -data/mono-cairo.pc -data/mono-nunit.pc -data/mono-options.pc -data/mono-lineeditor.pc -data/monodoc.pc -data/mono.web.pc -data/dotnet.pc -data/dotnet35.pc -data/wcf.pc -data/cecil.pc -data/system.web.extensions_1.0.pc -data/system.web.extensions.design_1.0.pc -data/system.web.mvc.pc -data/config -) - -###AC_OUTPUT([ -###mono-core.spec -###mono-uninstalled.pc -###scripts/mono-find-provides -###scripts/mono-find-requires -###mono/dis/Makefile -###mono/cil/Makefile -###mono/arch/Makefile -###mono/arch/x86/Makefile -###mono/arch/amd64/Makefile -###mono/arch/hppa/Makefile -###mono/arch/ppc/Makefile -###mono/arch/sparc/Makefile -###mono/arch/s390/Makefile -###mono/arch/s390x/Makefile -###mono/arch/arm/Makefile -###mono/arch/alpha/Makefile -###mono/arch/ia64/Makefile -###mono/arch/mips/Makefile -###mono/interpreter/Makefile -###mono/tests/Makefile -###mono/tests/tests-config -###mono/tests/assemblyresolve/Makefile -###mono/tests/cas/Makefile -###mono/tests/cas/assembly/Makefile -###mono/tests/cas/demand/Makefile -###mono/tests/cas/inheritance/Makefile -###mono/tests/cas/linkdemand/Makefile -###mono/tests/cas/threads/Makefile -###mono/benchmark/Makefile -###mono/monograph/Makefile -###mono/profiler/Makefile -###ikvm-native/Makefile -###scripts/Makefile -###man/Makefile -###web/Makefile -###docs/Makefile -###data/Makefile -###data/net_2_0/Makefile -###data/net_4_0/Makefile -###data/net_2_0/Browsers/Makefile -###data/mint.pc -###data/mono.pc -###data/mono-cairo.pc -###data/mono-nunit.pc -###data/mono-options.pc -###data/mono-lineeditor.pc -###data/monodoc.pc -###data/mono.web.pc -###data/dotnet.pc -###data/dotnet35.pc -###data/wcf.pc -###data/cecil.pc -###data/system.web.extensions_1.0.pc -###data/system.web.extensions.design_1.0.pc -###data/system.web.mvc.pc -###samples/Makefile -###support/Makefile -###data/config -###tools/Makefile -###tools/locale-builder/Makefile -###runtime/Makefile -###msvc/Makefile -###po/Makefile -###]) - -###if test x$platform_win32 = xyes; then -### # Get rid of 'cyg' prefixes in library names -### sed -e "s/\/cyg\//\/\//" libtool > libtool.new; mv libtool.new libtool; chmod 755 libtool -### # libtool seems to inherit -mno-cygwin from our CFLAGS, and uses it to compile its executable -### # wrapper scripts which use exec(). gcc has no problem compiling+linking this, but the resulting -### # executable doesn't work... -### sed -e "s,-mno-cygwin,,g" libtool > libtool.new; mv libtool.new libtool; chmod 755 libtool -###fi - -# FIXME: -set(mcs_INSTALL ${mono_build_root}/install-sh) - -### case $INSTALL in -### [[\\/$]]* | ?:[[\\/]]* ) set(mcs_INSTALL $INSTALL ;;) -### *) set(mcs_INSTALL $mono_build_root/$INSTALL ;;) -### esac - -# Compute a 4 part version number into myver from ${mono_version} -string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+).*" "\\1.\\2.\\3.\\4" myver "${mono_version}.0.0.0") - -set(config.make ${srcdir}/${mcsdir}/build/config.make) -# -# If we are cross compiling, we don't build in the mcs/ tree. Let us not clobber -# any existing config.make. This allows people to share the same source tree -# with different build directories, one native and one cross -# -if(NOT cross_compiling) - set(not_cross_compiling yes) -endif() -if(not_cross_compiling AND enable_mcs_build) - file(WRITE ${config.make} "prefix=${prefix} -exec_prefix=${exec_prefix} -sysconfdir=${sysconfdir} -mono_libdir=\${exec_prefix}/lib -MCS_FLAGS=$(PLATFORM_DEBUG_FLAGS) -IL_FLAGS=/debug -RUNTIME=${mono_build_root}/runtime/mono-wrapper -ILDISASM=${mono_build_root}/runtime/monodis-wrapper -INSTALL=${mcs_INSTALL} -MONO_VERSION=${myver} -") -endif() - -if(platform_darwin) - file(APPEND ${config.make} "PLATFORM=darwin\n") -endif() - -if (${TARGET} STREQUAL "AMD64" AND ${platform_win32} STREQUAL "no" AND AOT_SUPPORTED) - file(APPEND ${config.make} "ENABLE_AOT=1\n") -endif() - -if (DISABLE_MCS_DOCS) - file(APPEND ${config.make} "DISABLE_MCS_DOCS=yes\n") -endif() - -### # if we have an olive folder, override the default settings -### if test -d $olivedir; then - -### test -w $srcdir/$olivedir/build || chmod +w $srcdir/$olivedir/build - -### if test x$cross_compiling = xno && test x$enable_olive_build != xno; then -### echo "set(prefix $prefix" > $srcdir/$olivedir/build/config.make) -### echo "set(exec_prefix $exec_prefix" >> $srcdir/$olivedir/build/config.make) -### echo 'set(mono_libdir ${exec_prefix}/lib' >> $srcdir/$olivedir/build/config.make) -### echo 'MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS)' >> $srcdir/$olivedir/build/config.make -### echo "RUNTIME = $mono_build_root/runtime/mono-wrapper" >> $srcdir/$olivedir/build/config.make -### echo "MONO_VERSION = $myver" >> $srcdir/$olivedir/build/config.make -### if test x$with_moonlight = xyes; then -### echo "WITH_MOONLIGHT = yes" >> $srcdir/$olivedir/build/config.make -### fi -### fi -### fi - -if(NOT libgdiplus_loc) - set(libgdiplus_msg "assumed to be installed") -else() - set(libgdiplus_msg ${libgdiplus_loc}) -endif() - -message(STATUS -" - mcs source: ${mcs_topdir} - olive source: ${olive_topdir} - - GC: ${gc} - TLS: ${with_tls} - SIGALTSTACK: ${with_sigaltstack} - Engine: ${jit_status} - Moon Profile: ${with_moonlight} - 4.0 Alpha: ${with_profile4} - MonoTouch: ${with_monotouch} - JNI support: ${jdk_headers_found} - libgdiplus: ${libgdiplus_msg} - zlib: ${zlib_msg} - oprofile: ${with_oprofile} - BigArrays: ${enable_big_arrays} - DTrace: ${enable_dtrace} - Parallel Mark: ${enable_parallel_mark} - LLVM Back End: ${enable_llvm} - ${disabled} - -") - -if(NOT with_static_mono) - if(NOT platform_win32) - ac_msg_warn("Turning off static Mono is a risk, you might run into unexpected bugs") - endif() -endif() - -if(gc STREQUAL sgen) -message(" - IMPORTANT: - IMPORTANT: You have selected an experimental, work-in-progress - IMPORTANT: GC engine. This GC engine is currently not supported - IMPORTANT: and is not yet ready for use. - IMPORTANT: - IMPORTANT: There are known problems with it, use at your own risk. - IMPORTANT: -") -endif() - -if(enable_llvm) -message(" - IMPORTANT: - IMPORTANT: The LLVM Back End is experimental and does not work yet. - IMPORTANT: -") -endif() - -# Makefile.am - -### -rm -fr $(mcslib)/monolite-* -### -mkdir -p $(mcslib) -### test ! -d $(monolite) || test ! -d $(monolite).old || rm -fr $(monolite).old -### test ! -d $(monolite) || mv -f $(monolite) $(monolite).old -### cd $(mcslib) && { (wget -O- $(monolite_url) || curl $(monolite_url)) | gzip -d | tar xf - ; } -### cd $(mcslib) && mv -f monolite-* monolite - - -#### Keep in sync with SUBDIRS -##### 'tools' is not normally built -###DIST_SUBDIRS = po libgc $(eglib_dir) mono ikvm-native support data runtime scripts man samples web tools msvc docs - -###EXTRA_DIST= nls.m4 po.m4 progtest.m4 mono-uninstalled.pc.in build-mingw32.sh LICENSE mkinstalldirs - -###DISTCHECK_CONFIGURE_FLAGS = EXTERNAL_MCS=false EXTERNAL_RUNTIME=false - -#### Distribute the 'mcs' tree too -###dist-hook: -### test -d $(distdir)/mcs || mkdir $(distdir)/mcs -### d=`cd $(distdir)/mcs && pwd`; cd $(mcs_topdir) && $(MAKE) distdir=$$d dist-recursive - -###pkgconfigdir = $(libdir)/pkgconfig -###noinst_DATA = mono-uninstalled.pc -###DISTCLEANFILES= mono-uninstalled.pc - -###.PHONY: get-monolite-latest mcs-do-compiler-tests compiler-tests bootstrap-world - -#### building with monolite -set(mcslib ${mcs_topdir}/class/lib) -set(monolite ${mcslib}/monolite) -set(monolite_url http://mono.ximian.com/daily/monolite-latest.tar.gz) -add_custom_target(get-monolite-latest -COMMAND -rm -fr ${mcslib}/monolite-* -COMMAND -mkdir -p ${mcslib} -COMMAND test ! -d ${monolite} || test ! -d ${monolite}.old || rm -fr ${monolite}.old -COMMAND test ! -d ${monolite} || mv -f ${monolite} ${monolite}.old -COMMAND cd ${mcslib} && { (wget -O- ${monolite_url} || curl ${monolite_url}) | gzip -d | tar xf - \; } -COMMAND cd ${mcslib} && mv -f monolite-* monolite -) - -###compiler-tests: mcs-do-clean -### $(MAKE) all -### $(MAKE) mcs-do-compiler-tests - -###compiler-tests-net_2_0: -### -rm -f $(mcs_topdir)/build/common/Consts.cs.save -### -mv -f $(mcs_topdir)/build/common/Consts.cs $(mcs_topdir)/build/common/Consts.cs.save -### cd $(mcs_topdir) && $(MAKE) PROFILE=net_2_0_bootstrap clean -### cd $(mcs_topdir) && $(MAKE) PROFILE=net_2_0 clean -### -mv -f $(mcs_topdir)/build/common/Consts.cs.save $(mcs_topdir)/build/common/Consts.cs -### $(MAKE) all -### $(MAKE) build_profiles=net_2_0 mcs-do-compiler-tests - -###bootstrap-world: compiler-tests -### $(MAKE) install - -###bootstrap-world-net_2_0: compiler-tests-net_2_0 -### $(MAKE) install - -#### internal targets -###mcs-do-clean: -### cd runtime && $(MAKE) clean-local -### cd mono/tests && $(MAKE) clean -###mcs-do-compiler-tests: -### cd runtime && $(MAKE) test_select='TEST_SUBDIRS="tests errors"' check-local -### cd mono/tests && $(MAKE) check - -###win32getdeps: -### wget http://www.go-mono.com/archive/pkgconfig-0.11-20020310.zip -### wget http://www.go-mono.com/archive/glib-2.0.4-20020703.zip -### wget http://www.go-mono.com/archive/glib-dev-2.0.4-20020703.zip -### wget http://www.go-mono.com/archive/libiconv-1.7.zip -### wget http://www.go-mono.com/archive/libiconv-dev-1.7.zip -### wget http://www.go-mono.com/archive/libintl-0.10.40-20020101.zip -### unzip -n -d / pkgconfig-0.11-20020310.zip -### unzip -n -d / glib-2.0.4-20020703.zip -### unzip -n -d / glib-dev-2.0.4-20020703.zip -### unzip -n -d / libiconv-1.7.zip -### unzip -n -d / libiconv-dev-1.7.zip -### unzip -n -d / libintl-0.10.40-20020101.zip - -###win32setup: -### makensis /DMILESTONE=$(VERSION) /DSOURCE_INSTALL_DIR=$(SOURCE_INSTALL_DIR) /DBUILDNUM=$(BUILDNUM) monowiz.win32.nsi - -###bootstrap: all -### @echo "*** 'make bootstrap' is obsolete. Just run 'make' to perform a combined mono+mcs build" -### exit 1 - -###patch-quiet: -### find mono -name Makefile -exec scripts/patch-quiet.sh {} \; -### find libgc -name Makefile -exec scripts/patch-quiet.sh {} \; - -###update-csproj: -### (cd $(mcs_topdir)/build/csproj && gmcs genproj.cs) && (cd runtime; make V=1 extra_targets=csproj-local) diff --git a/configure.in b/configure.in index f997203e3f8..b9110a0f2c3 100644 --- a/configure.in +++ b/configure.in @@ -1823,6 +1823,7 @@ fi AC_CHECK_FUNCS(round) AC_CHECK_FUNCS(rint) +AC_CHECK_FUNCS(execvp) dnl **************************** dnl *** Look for /dev/random *** diff --git a/eglib/CMakeLists.txt b/eglib/CMakeLists.txt deleted file mode 100644 index cde7602aadd..00000000000 --- a/eglib/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(SUBDIRS src test) - -autoheader("config.h" null) - -foreach(subdir ${SUBDIRS}) - add_subdirectory(${subdir}) -endforeach() - diff --git a/eglib/src/CMakeLists.txt b/eglib/src/CMakeLists.txt deleted file mode 100644 index 2d134b4672d..00000000000 --- a/eglib/src/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -set(win_files - gdate-win32.c gdir-win32.c gfile-win32.c gmisc-win32.c - gmodule-win32.c gtimer-win32.c) - -set(unix_files - gdate-unix.c gdir-unix.c gfile-unix.c gmisc-unix.c - gmodule-unix.c gtimer-unix.c) - -if (MSVC) - set(os_files ${win_files}) -else(MSVC) - set(os_files ${unix_files}) -endif(MSVC) - -set(libeglib_la_SOURCES - ${os_files} - eglib-config.h - sort.frag.h - glib.h - garray.c - gerror.c - ghashtable.c - gmem.c - gmodule.h - goutput.c - gstr.c - gslist.c - gstring.c - gptrarray.c - glist.c - gqueue.c - gpath.c - gshell.c - gspawn.c - gfile.c - gfile-posix.c - gpattern.c - gmarkup.c - gutf8.c - gunicode.c - unicode-data.h) - -set(EXTRA_DIST eglib-config.h.in eglib-config.hw ${win_files} ${unix_files}) - -INCLUDE_DIRECTORIES(../ ${CMAKE_CURRENT_SOURCE_DIR}) -ADD_DEFINITIONS(${CFLAGS} -D_FORTIFY_SOURCE=2) -ADD_LIBRARY(eglib-static STATIC ${libeglib_la_SOURCES}) -ADD_LIBRARY(eglib SHARED ${libeglib_la_SOURCES}) - diff --git a/eglib/src/gmisc-unix.c b/eglib/src/gmisc-unix.c index 5d8cd2a739f..860b9304692 100644 --- a/eglib/src/gmisc-unix.c +++ b/eglib/src/gmisc-unix.c @@ -72,39 +72,57 @@ g_path_is_absolute (const char *filename) return (*filename == '/'); } -static pthread_mutex_t home_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t pw_lock = PTHREAD_MUTEX_INITIALIZER; static const gchar *home_dir; +static const gchar *user_name; -/* Give preference to /etc/passwd than HOME */ -const gchar * -g_get_home_dir (void) +static void +get_pw_data (void) { - if (home_dir == NULL){ - pthread_mutex_lock (&home_lock); - if (home_dir == NULL){ #ifdef HAVE_GETPWUID_R - struct passwd pw; - struct passwd *result; - char buf [4096]; + struct passwd pw; + struct passwd *result; + char buf [4096]; +#endif - if (getpwuid_r (getuid (), &pw, buf, 4096, &result) == 0) - home_dir = g_strdup (pw.pw_dir); + if (user_name != NULL) + return; + + pthread_mutex_lock (&pw_lock); + if (user_name != NULL) { + pthread_mutex_unlock (&pw_lock); + return; + } +#ifdef HAVE_GETPWUID_R + if (getpwuid_r (getuid (), &pw, buf, 4096, &result) == 0) { + home_dir = g_strdup (pw.pw_dir); + user_name = g_strdup (pw.pw_name); + } #endif - if (home_dir == NULL) - home_dir = g_getenv ("HOME"); - } - pthread_mutex_unlock (&home_lock); + if (home_dir == NULL) + home_dir = g_getenv ("HOME"); + + if (user_name == NULL) { + user_name = g_getenv ("USER"); + if (user_name == NULL) + user_name = "somebody"; } + pthread_mutex_unlock (&pw_lock); +} + +/* Give preference to /etc/passwd than HOME */ +const gchar * +g_get_home_dir (void) +{ + get_pw_data (); return home_dir; } const char * g_get_user_name (void) { - const char *retName = g_getenv ("USER"); - if (!retName) - retName = "somebody"; - return retName; + get_pw_data (); + return user_name; } static const char *tmp_dir; diff --git a/ikvm-native/CMakeLists.txt b/ikvm-native/CMakeLists.txt deleted file mode 100644 index 74c6a1ab87d..00000000000 --- a/ikvm-native/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - -ADD_DEFINITIONS(${GMODULE_CFLAGS}) -ADD_LIBRARY(ikvm_native SHARED jni.c os.c jni.h) -TARGET_LINK_LIBRARIES(ikvm_native ${GMODULE_LIBS}) \ No newline at end of file diff --git a/libgc/CMakeLists.txt b/libgc/CMakeLists.txt deleted file mode 100644 index d0a0a718bad..00000000000 --- a/libgc/CMakeLists.txt +++ /dev/null @@ -1,196 +0,0 @@ -# based on configure.in/Makefile.am, which is: - -# Copyright (c) 1999-2001 by Red Hat, Inc. All rights reserved. -# -# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED -# OR IMPLIED. ANY USE IS AT YOUR OWN RISK. -# -# Permission is hereby granted to use or copy this program -# for any purpose, provided the above notices are retained on all copies. -# Permission to modify the code and to distribute modified code is granted, -# provided the above notices are retained, and a notice that the code was -# modified is included with the above copyright notice. -# -# Original author: Tom Tromey -# Modified by: Grzegorz Jakacki - -# This is in sync with the configure.in/Makefile.am at r135583 - -# -# This is a cmake build file for libgc -# Only the functionality needed by mono is supported -# - -# FIXME: -add_definitions("-g -O2") - -set(THREADS ${libgc_threads}) - -set(THREADDLLIBS "") - -if (THREADS STREQUAL "no" OR THREADS STREQUAL "none" OR THREADS STREQUAL "single") - set(THREADS none) -endif() - -if (THREADS STREQUAL "posix" OR THREADS STREQUAL "pthreads") - set(THREADS posix) - set(THREADDLLIBS "-lpthread") - if (${host} MATCHES "x86-.*-linux.*|ia64-.*-linux.*|i386-.*-linux.*|i486-.*-linux.*|i586-.*-linux.*|i686-.*-linux.*|x86_64-.*-linux.*|alpha.*-.*-linux.*|s390.*-.*-linux.*|sparc.*-.*-linux.*|powerpc-.*-linux.*") - add_definitions(-DGC_LINUX_THREADS -D_REENTRANT) - set(parallel_mark_supported yes) - add_definitions(-DTHREAD_LOCAL_ALLOC) - elseif(${host} MATCHES ".*-linux.*") - add_definitions(-DGC_LINUX_THREADS -D_REENTRANT) - elseif(${host} MATCHES ".*-aix.*") - add_definitions(-DGC_AIX_THREADS -D_REENTRANT) - elseif(${host} MATCHES ".*-hpux.*") - message("Only HP/UX 11 threads are supported.") - add_definitions(-DGC_HPUX_THREADS -D_REENTRANT -D_POSIX_C_SOURCE=199506L) - add_definitions(-DTHREAD_LOCAL_ALLOC) - set(parallel_mark_supported yes) - set(THREADDLLIBS "-lpthread -lrt") - elseif(${host} ".*-.*-freebsd.*") - add_definitions(-DGC_FREEBSD_THREADS) - message(FATAL_ERROR "todo") -### if test "x$PTHREAD_CFLAGS" != "x"; then -### INCLUDES="$INCLUDES $PTHREAD_CFLAGS" -### fi -### if test "x$PTHREAD_LIBS" = "x"; then -### THREADDLLIBS=-pthread -### else -### THREADDLLIBS="$PTHREAD_LIBS" -### fi - elseif(${host} ".*-.*-freebsd.*") - add_definitions(-DGC_SOLARIS_THREADS -DGC_SOLARIS_PTHREADS) - elseif(${host} ".*-.*-irix.*") - add_definitions(-DGC_IRIX_THREADS) - elseif(${host} ".*-.*-cygwin.*") - add_definitons(-DGC_WIN32_THREADS) - elseif(${host} ".*-.*-darwin.*") - add_definitons(-DGC_DARWIN_THREADS -DTHREAD_LOCAL_ALLOC) - set(parallel_mark_supported yes) - elseif(${host} ".*-.*-netbsd.*") - add_definitions(-DGC_NETBSD_THREADS -DTHREAD_LOCAL_ALLOC) - set(parallel_mark_supported yes) - elseif(${host} ".*-.*-osf.*") - add_definitions(GC_OSF1_THREADS -DTHREAD_LOCAL_ALLOC) - set(parallel_mark_supported yes) - add_definitions(-pthread) - set(THREADDLLIBS "-lpthread -lrt") - else() - message(FATAL_ERROR "Pthreads not supported by the GC on this platform.") - endif() -endif() - -if(THREADS STREQUAL "win32") - add_definitions(GC_WIN32_THREADS) - # Wine getenv may not return NULL for missing entry - add_definitions(NO_GETENV) - if (enable_win32_dllmain) - add_definitions(gc_inside_dll) - endif() -endif() - -if(${host} MATCHES "powerpc-.*-darwin.*") - set(powerpc_darwin yes) -endif() - -if(parallel_mark_supported AND enable_parallel_mark) - add_definitions("-DPARALLEL_MARK") -endif() - -# Configuration of machine-dependent code - -ac_msg_checking("which machine-dependent code should be used") - -###AC_MSG_CHECKING( -###machdep= -###case "$host" in -### alpha-*-openbsd*) -### machdep="alpha_mach_dep.lo" -### if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then -### AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled) -### fi -### ;; -### alpha*-*-linux*) -### machdep="alpha_mach_dep.lo" -### ;; -### i?86-*-solaris2.[[89]]|i?86-*-solaris2.1?) -### AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED) -### ;; -### mipstx39-*-elf*) -### machdep="mips_ultrix_mach_dep.lo" -### AC_DEFINE(STACKBASE, __stackbase) -### AC_DEFINE(DATASTART_IS_ETEXT) -### ;; -### mips-dec-ultrix*) -### machdep="mips_ultrix_mach-dep.lo" -### ;; -### mips-nec-sysv*|mips-unknown-sysv*) -### ;; -### mips*-*-linux*) -### ;; -### mips-*-*) -### machdep="mips_sgi_mach_dep.lo" -### AC_DEFINE(NO_EXECUTE_PERMISSION) -### ;; -### sparc-*-netbsd*) -### machdep="sparc_netbsd_mach_dep.lo" -### ;; -### sparc-sun-solaris2.3) -### machdep="sparc_mach_dep.lo" -### AC_DEFINE(SUNOS53_SHARED_LIB) -### ;; -### sparc*-sun-solaris2.*) -### machdep="sparc_mach_dep.lo" -### ;; -### ia64-*-*) -### machdep="mach_dep.lo ia64_save_regs_in_stack.lo" -### ;; -###esac -if(NOT machdep) - set(machdep "mach_dep.c") -endif() -ac_msg_result("${machdep}") - -ac_msg_checking("for threads package to use") -ac_msg_result("${THREADS}") - -# Include defines that have become de facto standard. -# ALL_INTERIOR_POINTERS can be overridden in startup code. -add_definitions(-DSILENT -DNO_SIGNALS -DNO_EXECUTE_PERMISSION) -# AC_DEFINE(ALL_INTERIOR_POINTERS) - -# By default, make the library as general as possible. -add_definitions(-DJAVA_FINALIZATION -DGC_GCJ_SUPPORT -DATOMIC_UNCOLLECTABLE) - -add_definitions(-D_IN_LIBGC) - -set(SUBDIRS include doc) - -foreach(dir ${SUBDIRS}) - add_subdirectory(${dir}) -endforeach() - -set(top_srcdir ../) - -# .. is needed for mono/utils/mono-compiler.h -INCLUDE_DIRECTORIES(. .. include) -add_definitions(${CPPFLAGS}) - -if(powerpc_darwin) - set(asm_libgc_sources powerpc_darwin_mach_dep.s) -endif() - -set(libmonogc_la_SOURCES - allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c - dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c - malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c - obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c - solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c - backgraph.c win32_threads.c - pthread_support.c pthread_stop_world.c darwin_stop_world.c - ${asm_libgc_sources} ${machdep}) - -add_library(monogc-static STATIC ${libmonogc_la_SOURCES}) -target_link_libraries (${THREADDLLIBS} ${UNWINDLIBS}) diff --git a/libgc/Makefile.am b/libgc/Makefile.am index 735cc3bdaf8..0700ae8b5b4 100644 --- a/libgc/Makefile.am +++ b/libgc/Makefile.am @@ -47,12 +47,12 @@ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \ backgraph.c win32_threads.c \ pthread_support.c pthread_stop_world.c darwin_stop_world.c \ -$(asm_libgc_sources) +mach_dep.c $(asm_libgc_sources) # Include THREADDLLIBS here to ensure that the correct versions of # linuxthread semaphore functions get linked: -libmonogc_la_LIBADD = @addobjs@ $(THREADDLLIBS) $(UNWINDLIBS) -libmonogc_la_DEPENDENCIES = @addobjs@ +libmonogc_la_LIBADD = $(THREADDLLIBS) $(UNWINDLIBS) +libmonogc_la_DEPENDENCIES = libmonogc_la_LDFLAGS = -version-info 1:2:0 EXTRA_libmonogc_la_SOURCES = alpha_mach_dep.S \ @@ -93,7 +93,7 @@ endif #TESTS = gctest $(extra_checks) ## FIXME: relies on internal code generated by automake. -all_objs = @addobjs@ $(libgc_la_OBJECTS) +all_objs = $(libgc_la_OBJECTS) $(all_objs) : include/private/gcconfig.h include/private/gc_priv.h \ include/private/gc_hdrs.h include/gc.h include/gc_gcj.h include/gc_mark.h @@ -113,7 +113,7 @@ endif ## We have our own definition of LTCOMPILE because we want to use our ## CFLAGS, not those passed in from the top level make. -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \ +LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(INCLUDES) \ -I$(top_srcdir)/include $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@ diff --git a/libgc/acinclude.m4 b/libgc/acinclude.m4 index 510967b4f4c..16c7da8151b 100644 --- a/libgc/acinclude.m4 +++ b/libgc/acinclude.m4 @@ -1,47 +1,181 @@ -# -# -# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED -# OR IMPLIED. ANY USE IS AT YOUR OWN RISK. -# -# Permission is hereby granted to use or copy this program -# for any purpose, provided the above notices are retained on all copies. -# Permission to modify the code and to distribute modified code is granted, -# provided the above notices are retained, and a notice that the code was -# modified is included with the above copyright notice. -# -# Modified by: Grzegorz Jakacki - -# GC_SET_VERSION -# sets and AC_DEFINEs GC_VERSION_MAJOR, GC_VERSION_MINOR and GC_ALPHA_VERSION -# based on the contents of PACKAGE_VERSION; PACKAGE_VERSION must conform to -# [0-9]+[.][0-9]+(alpha[0.9]+)? -# in lex syntax; if there is no alpha number, GC_ALPHA_VERSION is empty -# -AC_DEFUN(GC_SET_VERSION, [ - AC_MSG_CHECKING(GC version numbers) - GC_VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([[0-9]][[0-9]]*\)[[.]].*$/\1/g'` - GC_VERSION_MINOR=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]]\([[0-9]][[0-9]]*\).*$/\1/g'` - GC_ALPHA_VERSION=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]][[0-9]]*//'` - - case "$GC_ALPHA_VERSION" in - alpha*) - GC_ALPHA_VERSION=`echo $GC_ALPHA_VERSION \ - | sed 's/alpha\([[0-9]][[0-9]]*\)/\1/'` ;; - *) GC_ALPHA_MAJOR='' ;; - esac - - if test :$GC_VERSION_MAJOR: = :: \ - -o :$GC_VERSION_MINOR: = :: ; - then - AC_MSG_RESULT(invalid) - AC_MSG_ERROR([nonconforming PACKAGE_VERSION='$PACKAGE_VERSION']) - fi - - AC_DEFINE_UNQUOTED(GC_VERSION_MAJOR, $GC_VERSION_MAJOR) - AC_DEFINE_UNQUOTED(GC_VERSION_MINOR, $GC_VERSION_MINOR) - if test :$GC_ALPHA_VERSION: != :: ; then - AC_DEFINE_UNQUOTED(GC_ALPHA_VERSION, $GC_ALPHA_VERSION) - fi - AC_MSG_RESULT(major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \ -${GC_ALPHA_VERSION:+alpha=}$GC_ALPHA_VERSION) +dnl dolt, a replacement for libtool +dnl Copyright © 2007-2008 Josh Triplett +dnl Copying and distribution of this file, with or without modification, +dnl are permitted in any medium without royalty provided the copyright +dnl notice and this notice are preserved. +dnl +dnl To use dolt, invoke the DOLT macro immediately after the libtool macros. +dnl Optionally, copy this file into acinclude.m4, to avoid the need to have it +dnl installed when running autoconf on your project. + +AC_DEFUN([DOLT], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +# dolt, a replacement for libtool +# Josh Triplett +AC_PATH_PROG(DOLT_BASH, bash) +AC_MSG_CHECKING([if dolt supports this host]) +dolt_supported=yes +if test x$DOLT_BASH = x; then + dolt_supported=no +fi +if test x$GCC != xyes; then + dolt_supported=no +fi +case $host in +i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ +|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*) + pic_options='-fPIC' + ;; +?86-pc-cygwin*|i?86-pc-cygwin*) + pic_options='-DDLL_EXPORT' + ;; +i?86-apple-darwin*) + pic_options='-fno-common' + ;; +*) + dolt_supported=no + ;; +esac +if test x$dolt_supported = xno ; then + AC_MSG_RESULT([no, falling back to libtool]) + LTCOMPILE='$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(COMPILE)' + LTCXXCOMPILE='$(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXXCOMPILE)' +else + AC_MSG_RESULT([yes, replacing libtool]) + +dnl Start writing out doltcompile. + cat <<__DOLTCOMPILE__EOF__ >doltcompile +#!$DOLT_BASH +__DOLTCOMPILE__EOF__ + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +args=("$[]@") +for ((arg=0; arg<${#args@<:@@@:>@}; arg++)) ; do + if test x"${args@<:@$arg@:>@}" = x-o ; then + objarg=$((arg+1)) + break + fi +done +if test x$objarg = x ; then + echo 'Error: no -o on compiler command line' 1>&2 + exit 1 +fi +lo="${args@<:@$objarg@:>@}" +obj="${lo%.lo}" +if test x"$lo" = x"$obj" ; then + echo "Error: libtool object file name \"$lo\" does not end in .lo" 1>&2 + exit 1 +fi +objbase="${obj##*/}" +__DOLTCOMPILE__EOF__ + +dnl Write out shared compilation code. + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +libobjdir="${obj%$objbase}.libs" +if test ! -d "$libobjdir" ; then + mkdir_out="$(mkdir "$libobjdir" 2>&1)" + mkdir_ret=$? + if test "$mkdir_ret" -ne 0 && test ! -d "$libobjdir" ; then + echo "$mkdir_out" 1>&2 + exit $mkdir_ret + fi +fi +pic_object="$libobjdir/$objbase.o" +args@<:@$objarg@:>@="$pic_object" +__DOLTCOMPILE__EOF__ + cat <<__DOLTCOMPILE__EOF__ >>doltcompile +"\${args@<:@@@:>@}" $pic_options -DPIC || exit \$? +__DOLTCOMPILE__EOF__ + fi + +dnl Write out static compilation code. +dnl Avoid duplicate compiler output if also building shared objects. + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +non_pic_object="$obj.o" +args@<:@$objarg@:>@="$non_pic_object" +__DOLTCOMPILE__EOF__ + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args@<:@@@:>@}" >/dev/null 2>&1 || exit $? +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args@<:@@@:>@}" || exit $? +__DOLTCOMPILE__EOF__ + fi + fi + +dnl Write out the code to write the .lo file. +dnl The second line of the .lo file must match "^# Generated by .*libtool" + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +{ +echo "# $lo - a libtool object file" +echo "# Generated by doltcompile, not libtool" +__DOLTCOMPILE__EOF__ + + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "pic_object='.libs/${objbase}.o'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo pic_object=none +__DOLTCOMPILE__EOF__ + fi + + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "non_pic_object='${objbase}.o'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo non_pic_object=none +__DOLTCOMPILE__EOF__ + fi + + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +} > "$lo" +__DOLTCOMPILE__EOF__ + +dnl Done writing out doltcompile; substitute it for libtool compilation. + chmod +x doltcompile + LTCOMPILE='$(top_builddir)/doltcompile $(COMPILE)' + LTCXXCOMPILE='$(top_builddir)/doltcompile $(CXXCOMPILE)' + +dnl automake ignores LTCOMPILE and LTCXXCOMPILE when it has separate CFLAGS for +dnl a target, so write out a libtool wrapper to handle that case. +dnl Note that doltlibtool does not handle inferred tags or option arguments +dnl without '=', because automake does not use them. + cat <<__DOLTLIBTOOL__EOF__ > doltlibtool +#!$DOLT_BASH +__DOLTLIBTOOL__EOF__ + cat <<'__DOLTLIBTOOL__EOF__' >>doltlibtool +top_builddir_slash="${0%%doltlibtool}" +: ${top_builddir_slash:=./} +args=() +modeok=false +tagok=false +for arg in "$[]@"; do + case "$arg" in + --mode=compile) modeok=true ;; + --tag=CC|--tag=CXX) tagok=true ;; + --quiet) ;; + *) args@<:@${#args[@]}@:>@="$arg" ;; + esac +done +if $modeok && $tagok ; then + . ${top_builddir_slash}doltcompile "${args@<:@@@:>@}" +else + exec ${top_builddir_slash}libtool "$[]@" +fi +__DOLTLIBTOOL__EOF__ + +dnl Done writing out doltlibtool; substitute it for libtool. + chmod +x doltlibtool + LIBTOOL='$(top_builddir)/doltlibtool' +fi +AC_SUBST(LTCOMPILE) +AC_SUBST(LTCXXCOMPILE) +# end dolt ]) diff --git a/libgc/configure.in b/libgc/configure.in index 2bd596bb8c4..865988a2b4f 100644 --- a/libgc/configure.in +++ b/libgc/configure.in @@ -344,6 +344,8 @@ AC_SUBST(addlibs) AC_SUBST(addtests) AC_PROG_LIBTOOL +# Use dolt (http://dolt.freedesktop.org/) instead of libtool for building. +DOLT # # Check for AViiON Machines running DGUX diff --git a/man/mprof-report.1 b/man/mprof-report.1 index 142a916da10..5c3be5d7a56 100644 --- a/man/mprof-report.1 +++ b/man/mprof-report.1 @@ -101,16 +101,16 @@ See the \f[I]maxframes\f[] option to control this behaviour. \f[I]calls\f[] enables method enter/leave events if they were disabled by another option like \f[I]heapshot\f[]. .IP \[bu] 2 -\f[I]heapshot\f[]: collect heap shot data at each major collection. +\f[I]heapshot[=MODE]\f[]: collect heap shot data at each major +collection. The frequency of the heap shots can be changed with the -\f[I]hsmode\f[] option below. +\f[I]MODE\f[] parameter. When this option is used allocation events and method enter/leave events are not recorded by default: if they are needed, they need to be enabled explicitly. -.IP \[bu] 2 -\f[I]hsmode=MODE\f[]: modify the default heap shot frequency -according to MODE. -hsmode can be used multiple times with different modes: in that +The optional parameter \f[I]MODE\f[] can modify the default heap +shot frequency. +heapshot can be used multiple times with different modes: in that case a heap shot is taken if either of the conditions are met. MODE can be one of: .RS 2 @@ -140,18 +140,28 @@ call chain depth is bigger than NUM. format. .IP \[bu] 2 \f[I]output=OUTSPEC\f[]: instead of writing the profiling data to -the output.mlpd file, do according to \f[I]OUTSPEC\f[]: +the output.mlpd file, substitute \f[I]%p\f[] in \f[I]OUTSPEC\f[] +with the current process id and \f[I]%t\f[] with the current date +and time, then do according to \f[I]OUTSPEC\f[]: .RS 2 .IP \[bu] 2 if \f[I]OUTSPEC\f[] begins with a \f[I]|\f[] character, execute the rest as a program and feed the data to its standard input .IP \[bu] 2 -otherwise write the data the the named file +if \f[I]OUTSPEC\f[] begins with a \f[I]-\f[] character, use the +rest of OUTSPEC as the filename, but force overwrite any existing +file by that name +.IP \[bu] 2 +otherwise write the data the the named file: note that is a file by +that name already exists, a warning is issued and profiling is +disabled. .RE .IP \[bu] 2 \f[I]report\f[]: the profiling data is sent to mprof-report, which will print a summary report. This is equivalent to the option: \f[B]output=mprof-report\ -\f[]. +If the \f[I]output\f[] option is specified as well, the report will +be written to the output file instead of the console. .SS Analyzing the profile data .PP Currently there is a command line program (\f[I]mprof-report\f[]) @@ -347,8 +357,8 @@ completely, by setting it to 0. The other major source of data is the heapshot profiler option: especially if the managed heap is big, since every object needs to be inspected. -The \f[I]hsmode\f[] option can be used to reduce the frequency of -the heap shots. +The \f[I]MODE\f[] parameter of the \f[I]heapshot\f[] option can be +used to reduce the frequency of the heap shots. .SS Reduce the timestamp overhead .PP On many operating systems or architectures what actually slows down @@ -401,15 +411,14 @@ option. .PP Heap shot data can also be huge: by default it is collected at each major collection. -To reduce the frequency, you can use the \f[I]hsmode\f[] profiler -option to collect for example every 5 collections (including major -and minor): +To reduce the frequency, you can specify a heapshot mode: for +example to collect every 5 collections (including major and minor): .PP -\f[B]hsmode=5gc\f[] +\f[B]heapshot=5gc\f[] .PP or when at least 5 seconds passed since the last heap shot: .PP -\f[B]hsmode=5000ms\f[] +\f[B]heapshot=5000ms\f[] .SS Compressing the data .PP To reduce the amout of disk space used by the data, the data can be diff --git a/mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/RuntimeBinderContext.cs b/mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/RuntimeBinderContext.cs index afdb7f17db2..035b939a65b 100644 --- a/mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/RuntimeBinderContext.cs +++ b/mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/RuntimeBinderContext.cs @@ -55,8 +55,7 @@ namespace Microsoft.CSharp.RuntimeBinder public Compiler.MemberCore CurrentMemberDefinition { get { - // For operators and methods - return new Compiler.ModuleContainer (currentType.Assembly); + return null; } } diff --git a/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs b/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs index 4b53d911c07..687442e2ea7 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs @@ -167,25 +167,27 @@ namespace System.Linq.Parallel for (int i = 0; i < tasks.Length; i++) { int index = i; - bool firstRun = true; tasks[i] = Task.Factory.StartNew (() => { - foreach (T item in enumerables[index]) { - // This is from specific operators - if (options.ImplementerToken.IsCancellationRequested) - break; - if (options.Token.IsCancellationRequested) - throw new OperationCanceledException (options.Token); - - if (firstRun && seedFunc == null) { - firstRun = false; - // HACK: TODO: omgwtfitsuckssomuch - locals[index] = (U)(object)item; - continue; + var enumerator = enumerables[index].GetEnumerator (); + var token = options.Token; + var implementerToken = options.ImplementerToken; + + try { + if (seedFunc == null) { + if (!enumerator.MoveNext ()) + return; + locals[index] = (U)(object)enumerator.Current; } - U acc = locals[index]; - locals[index] = localCall (acc, item); + while (enumerator.MoveNext ()) { + if (implementerToken.IsCancellationRequested) + break; + token.ThrowIfCancellationRequested (); + locals[index] = localCall (locals[index], enumerator.Current); + } + } finally { + enumerator.Dispose (); } }, options.Token); } diff --git a/mcs/class/System.Web.Extensions/System.Web.UI/AsyncPostBackTrigger.cs b/mcs/class/System.Web.Extensions/System.Web.UI/AsyncPostBackTrigger.cs index 22d436eb6d5..52f7402d154 100644 --- a/mcs/class/System.Web.Extensions/System.Web.UI/AsyncPostBackTrigger.cs +++ b/mcs/class/System.Web.Extensions/System.Web.UI/AsyncPostBackTrigger.cs @@ -69,9 +69,13 @@ namespace System.Web.UI string ctrlUniqueID = ctrl != null ? ctrl.UniqueID : null; if (ctrlUniqueID == null) return false; - - if (String.Compare (Owner.ScriptManager.AsyncPostBackSourceElementID, ctrlUniqueID, StringComparison.Ordinal) == 0) + + string asyncPostBackElementID = Owner.ScriptManager.AsyncPostBackSourceElementID; + if (String.Compare (asyncPostBackElementID, ctrlUniqueID, StringComparison.Ordinal) == 0) return true; + else if (asyncPostBackElementID.StartsWith (ctrlUniqueID + "$", StringComparison.Ordinal)) + return true; + return false; } @@ -109,7 +113,7 @@ namespace System.Web.UI } public override string ToString () { - return String.Format ("AsyncPostBack: {0}.{1}", ControlID, EventName); + return String.Format ("AsyncPostBackTrigger: {0}.{1}", ControlID, EventName); } } } \ No newline at end of file diff --git a/mcs/class/System.Web/System.Web.Caching/Cache.cs b/mcs/class/System.Web/System.Web.Caching/Cache.cs index 0e114dbbba0..2baea96cef2 100644 --- a/mcs/class/System.Web/System.Web.Caching/Cache.cs +++ b/mcs/class/System.Web/System.Web.Caching/Cache.cs @@ -31,6 +31,7 @@ using System.Threading; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Security.Permissions; using System.Web.Configuration; @@ -40,6 +41,9 @@ namespace System.Web.Caching [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] public sealed class Cache: IEnumerable { + const int LOW_WATER_MARK = 10000; // Target number of items if high water mark is reached + const int HIGH_WATER_MARK = 15000; // We start collection after exceeding this count + public static readonly DateTime NoAbsoluteExpiration = DateTime.MaxValue; public static readonly TimeSpan NoSlidingExpiration = TimeSpan.Zero; @@ -58,7 +62,7 @@ namespace System.Web.Caching // Thread.Abort happened right after that during the stloc instruction to set the // boolean flag. Once CERs are supported we can use the boolean flag reliably. ReaderWriterLockSlim cacheLock; - Dictionary cache; + CacheItemLRU cache; CacheItemPriorityQueue timedItems; Timer expirationTimer; long expirationTimerPeriod = 0; @@ -124,7 +128,7 @@ namespace System.Web.Caching public Cache () { cacheLock = new ReaderWriterLockSlim (); - cache = new Dictionary (StringComparer.Ordinal); + cache = new CacheItemLRU (this, HIGH_WATER_MARK, LOW_WATER_MARK); } public int Count { @@ -136,25 +140,13 @@ namespace System.Web.Caching set { Insert (key, value); } } - CacheItem GetCacheItem (string key) - { - if (key == null) - return null; - - CacheItem ret; - if (cache.TryGetValue (key, out ret)) - return ret; - return null; - } - + // Must ALWAYS be called with the cache write lock held CacheItem RemoveCacheItem (string key) { if (key == null) return null; - CacheItem ret = null; - if (!cache.TryGetValue (key, out ret)) - return null; + CacheItem ret = cache [key]; if (timedItems != null) timedItems.OnItemDisable (ret); @@ -171,7 +163,7 @@ namespace System.Web.Caching try { cacheLock.EnterWriteLock (); - CacheItem it = GetCacheItem (key); + CacheItem it = cache [key]; if (it != null) return it.Value; @@ -188,7 +180,7 @@ namespace System.Web.Caching { try { cacheLock.EnterUpgradeableReadLock (); - CacheItem it = GetCacheItem (key); + CacheItem it = cache [key]; if (it == null) return null; @@ -299,7 +291,7 @@ namespace System.Web.Caching if (doLock) cacheLock.EnterWriteLock (); - ci = GetCacheItem (key); + ci = cache [key]; if (ci != null) SetItemTimeout (ci, absoluteExpiration, slidingExpiration, ci.OnRemoveCallback, null, key, false); } finally { @@ -329,18 +321,17 @@ namespace System.Web.Caching try { if (doLock) cacheLock.EnterWriteLock (); - - if (ci.Timer != null) { - ci.Timer.Dispose (); - ci.Timer = null; - } - if (key != null) + if (key != null) { cache [key] = ci; + cache.EvictIfNecessary (); + } ci.LastChange = DateTime.Now; - if (!disableExpiration && ci.AbsoluteExpiration != NoAbsoluteExpiration) + if (!disableExpiration && ci.AbsoluteExpiration != NoAbsoluteExpiration) { + ci.IsTimedItem = true; EnqueueTimedItem (ci); + } } finally { if (doLock) { // See comment at the top of the file, above cacheLock declaration @@ -380,7 +371,7 @@ namespace System.Web.Caching return Remove (key, CacheItemRemovedReason.Removed, true, true); } - object Remove (string key, CacheItemRemovedReason reason, bool doLock, bool invokeCallback) + internal object Remove (string key, CacheItemRemovedReason reason, bool doLock, bool invokeCallback) { CacheItem it = null; try { @@ -395,11 +386,8 @@ namespace System.Web.Caching } } + object ret = null; if (it != null) { - Timer t = it.Timer; - if (t != null) - t.Dispose (); - if (it.Dependency != null) { it.Dependency.SetCache (null); it.Dependency.DependencyChanged -= new EventHandler (OnDependencyChanged); @@ -412,38 +400,25 @@ namespace System.Web.Caching //TODO: anything to be done here? } } - object ret = it.Value; + ret = it.Value; it.Value = null; it.Key = null; it.Dependency = null; it.OnRemoveCallback = null; it.OnUpdateCallback = null; + it = null; + } - return ret; - } else - return null; + return ret; } // Used when shutting down the application so that // session_end events are sent for all sessions. internal void InvokePrivateCallbacks () { - CacheItemRemovedReason reason = CacheItemRemovedReason.Removed; try { cacheLock.EnterReadLock (); - foreach (string key in cache.Keys) { - CacheItem item = GetCacheItem (key); - if (item.Disabled) - continue; - - if (item != null && item.OnRemoveCallback != null) { - try { - item.OnRemoveCallback (key, item.Value, reason); - } catch { - //TODO: anything to be done here? - } - } - } + cache.InvokePrivateCallbacks (); } finally { // See comment at the top of the file, above cacheLock declaration cacheLock.ExitReadLock (); @@ -452,11 +427,10 @@ namespace System.Web.Caching public IDictionaryEnumerator GetEnumerator () { - ArrayList list = new ArrayList (); + List list = null; try { cacheLock.EnterReadLock (); - foreach (CacheItem it in cache.Values) - list.Add (it); + list = cache.ToList (); } finally { // See comment at the top of the file, above cacheLock declaration cacheLock.ExitReadLock (); @@ -570,17 +544,20 @@ namespace System.Web.Caching internal void CheckDependencies () { - IList list; try { cacheLock.EnterWriteLock (); - list = new List (); - foreach (CacheItem it in cache.Values) - list.Add (it); - - foreach (CacheItem it in list) { + List list = cache.SelectItems (it => { + if (it == null) + return false; if (it.Dependency != null && it.Dependency.HasChanged && !NeedsUpdate (it, CacheItemUpdateReason.DependencyChanged, false)) - Remove (it.Key, CacheItemRemovedReason.DependencyChanged, false, true); - } + return true; + return false; + }); + + foreach (CacheItem it in list) + Remove (it.Key, CacheItemRemovedReason.DependencyChanged, false, true); + list.Clear (); + list.TrimExcess (); } finally { // See comment at the top of the file, above cacheLock declaration cacheLock.ExitWriteLock (); @@ -591,7 +568,7 @@ namespace System.Web.Caching { try { cacheLock.EnterReadLock (); - CacheItem it = GetCacheItem (key); + CacheItem it = cache [key]; if (it == null) return DateTime.MaxValue; diff --git a/mcs/class/System.Web/System.Web.Caching/CacheItem.cs b/mcs/class/System.Web/System.Web.Caching/CacheItem.cs index 32629a8299c..0158066c3dc 100644 --- a/mcs/class/System.Web/System.Web.Caching/CacheItem.cs +++ b/mcs/class/System.Web/System.Web.Caching/CacheItem.cs @@ -44,14 +44,14 @@ namespace System.Web.Caching public DateTime LastChange; public long ExpiresAt; public bool Disabled; - public Timer Timer; + public bool IsTimedItem; public Guid Guid; - + public CacheItem () { Guid = Guid.NewGuid (); } - + public override string ToString () { return String.Format ("CacheItem [{0}]\n[{1}][{2}][{3}]", this.Guid, Key, Disabled, ExpiresAt > 0 ? new DateTime (ExpiresAt).ToString () : "0"); diff --git a/mcs/class/System.Web/System.Web.Caching/CacheItemEnumerator.cs b/mcs/class/System.Web/System.Web.Caching/CacheItemEnumerator.cs index 3c3129005e7..09951571b90 100644 --- a/mcs/class/System.Web/System.Web.Caching/CacheItemEnumerator.cs +++ b/mcs/class/System.Web/System.Web.Caching/CacheItemEnumerator.cs @@ -4,7 +4,7 @@ // Author(s): // Lluis Sanchez // -// (C) 2005-2009 Novell, Inc (http://novell.com) +// (C) 2005-2010 Novell, Inc (http://novell.com) // // // Permission is hereby granted, free of charge, to any person obtaining @@ -28,15 +28,16 @@ // using System; using System.Collections; +using System.Collections.Generic; namespace System.Web.Caching { sealed class CacheItemEnumerator: IDictionaryEnumerator { - ArrayList list; + List list; int pos = -1; - public CacheItemEnumerator (ArrayList list) + public CacheItemEnumerator (List list) { this.list = list; } @@ -45,7 +46,7 @@ namespace System.Web.Caching get { if (pos < 0 || pos >= list.Count) throw new InvalidOperationException (); - return list [pos] as CacheItem; + return list [pos]; } } diff --git a/mcs/class/System.Web/System.Web.Caching/CacheItemLRU.cs b/mcs/class/System.Web/System.Web.Caching/CacheItemLRU.cs new file mode 100644 index 00000000000..b31bfade85b --- /dev/null +++ b/mcs/class/System.Web/System.Web.Caching/CacheItemLRU.cs @@ -0,0 +1,201 @@ +// +// A simple LRU cache used for tracking the cache items +// +// Authors: +// Miguel de Icaza (miguel@gnome.org) +// +// Copyright 2010 Miguel de Icaza +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +using System; +using System.Collections.Generic; + +namespace System.Web.Caching +{ + sealed class CacheItemLRU + { + public delegate bool SelectItemsQualifier (CacheItem item); + + Dictionary> dict; + Dictionary, string> revdict; + LinkedList list; + Cache owner; + + // High/Low water mark is here to avoid situations when we hit a limit, evict an + // entry, add another one and have to evict again because the limit was hit. When we + // hit the high water limit, we evict until we reach the low water mark to avoid the + // situation. + int highWaterMark, lowWaterMark; + bool needsEviction; + + public int Count { + get { return dict.Count; } + } + + public CacheItemLRU (Cache owner, int highWaterMark, int lowWaterMark) + { + list = new LinkedList (); + dict = new Dictionary> (StringComparer.Ordinal); + revdict = new Dictionary, string> (); + + this.highWaterMark = highWaterMark; + this.lowWaterMark = lowWaterMark; + this.owner = owner; + } + + public bool TryGetValue (string key, out CacheItem value) + { + LinkedListNode item; + + if (dict.TryGetValue (key, out item)) { + value = item.Value; + return true; + } + value = null; + return false; + } + + // Must ALWAYS be called with the owner's write lock held + public void EvictIfNecessary () + { + if (!needsEviction) + return; + + for (int i = dict.Count; i > lowWaterMark; i--) { + var key = revdict [list.Last]; + + owner.Remove (key, CacheItemRemovedReason.Underused, false, true); + } + } + + // Must ALWAYS be called with the owner's read lock held + public void InvokePrivateCallbacks () + { + foreach (var de in dict) { + CacheItem item = de.Value.Value; + if (item == null || item.Disabled) + continue; + + if (item.OnRemoveCallback != null) { + try { + item.OnRemoveCallback (de.Key, item.Value, CacheItemRemovedReason.Removed); + } catch { + //TODO: anything to be done here? + } + } + } + } + + // Must ALWAYS be called with the owner's write lock held + public List SelectItems (SelectItemsQualifier qualifier) + { + var ret = new List (); + + foreach (LinkedListNode node in dict.Values) { + CacheItem item = node.Value; + + if (qualifier (item)) + ret.Add (item); + } + + return ret; + } + + // Must ALWAYS be called with the owner's read lock held + public List ToList () + { + var ret = new List (); + + if (dict.Count == 0) + return ret; + + foreach (LinkedListNode node in dict.Values) + ret.Add (node.Value); + + return ret; + } + + public void Remove (string key) + { + if (key == null) + return; + + LinkedListNode node; + if (!dict.TryGetValue (key, out node)) + return; + + CacheItem item = node.Value; + dict.Remove (key); + + if (item == null || item.Priority != CacheItemPriority.NotRemovable) { + revdict.Remove (node); + list.Remove (node); + } + } + + public CacheItem this [string key] { + get { + if (key == null) + return null; + + LinkedListNode node; + CacheItem item; + + if (dict.TryGetValue (key, out node)){ + item = node.Value; + if (item == null || item.Priority != CacheItemPriority.NotRemovable) { + list.Remove (node); + list.AddFirst (node); + } + + return item; + } + + return null; + } + + set { + LinkedListNode node; + + if (dict.TryGetValue (key, out node)){ + // If we already have a key, move it to the front + list.Remove (node); + if (value == null || value.Priority != CacheItemPriority.NotRemovable) + list.AddFirst (node); + else + revdict.Remove (node); + + node.Value = value; + return; + } + needsEviction = dict.Count >= highWaterMark; + + // Adding new node + node = new LinkedListNode (value); + if (value == null || value.Priority != CacheItemPriority.NotRemovable) { + list.AddFirst (node); + revdict [node] = key; + } + + dict [key] = node; + } + } + } +} diff --git a/mcs/class/System.Web/System.Web.SessionState_2.0/SessionInProcHandler.cs b/mcs/class/System.Web/System.Web.SessionState_2.0/SessionInProcHandler.cs index 6ec6245d68d..24175a79c1f 100644 --- a/mcs/class/System.Web/System.Web.SessionState_2.0/SessionInProcHandler.cs +++ b/mcs/class/System.Web/System.Web.SessionState_2.0/SessionInProcHandler.cs @@ -5,6 +5,7 @@ // Marek Habersack // // (C) 2006 Marek Habersack +// (C) 2010 Novell, Inc (http://novell.com/) // // @@ -46,7 +47,7 @@ namespace System.Web.SessionState public ISessionStateItemCollection items; public DateTime lockedTime; public DateTime expiresAt; - public ReaderWriterLock rwlock; + public ReaderWriterLockSlim rwlock; public Int32 lockId; public int timeout; public bool resettingTimeout; @@ -60,11 +61,26 @@ namespace System.Web.SessionState this.staticItems = null; this.lockedTime = DateTime.MinValue; this.expiresAt = DateTime.MinValue; - this.rwlock = new ReaderWriterLock (); + this.rwlock = new ReaderWriterLockSlim (); this.lockId = Int32.MinValue; this.timeout = 0; this.resettingTimeout = false; } + + public void Dispose () + { + if (rwlock != null) { + rwlock.Dispose (); + rwlock = null; + } + staticItems = null; + items = null; + } + + ~InProcSessionItem () + { + Dispose (); + } } internal class SessionInProcHandler : SessionStateStoreProviderBase @@ -114,6 +130,10 @@ namespace System.Web.SessionState public override void EndRequest (HttpContext context) { + if (staticObjects != null) { + staticObjects.GetObjects ().Clear (); + staticObjects = null; + } } SessionStateStoreData GetItemInternal (HttpContext context, @@ -138,18 +158,26 @@ namespace System.Web.SessionState if (item == null) return null; - + + bool readLocked = false, writeLocked = false; try { - item.rwlock.AcquireReaderLock (lockAcquireTimeout); + if (item.rwlock.TryEnterUpgradeableReadLock (lockAcquireTimeout)) + readLocked = true; + else + throw new ApplicationException ("Failed to acquire lock"); + if (item.locked) { locked = true; lockAge = DateTime.UtcNow.Subtract (item.lockedTime); lockId = item.lockId; return null; } - item.rwlock.ReleaseReaderLock (); + if (exclusive) { - item.rwlock.AcquireWriterLock (lockAcquireTimeout); + if (item.rwlock.TryEnterWriteLock (lockAcquireTimeout)) + writeLocked = true; + else + throw new ApplicationException ("Failed to acquire lock"); item.locked = true; item.lockedTime = DateTime.UtcNow; item.lockId++; @@ -169,10 +197,10 @@ namespace System.Web.SessionState // we want such errors to be passed to the application. throw; } finally { - if (item.rwlock.IsReaderLockHeld) - item.rwlock.ReleaseReaderLock (); - if (item.rwlock.IsWriterLockHeld) - item.rwlock.ReleaseWriterLock (); + if (writeLocked) + item.rwlock.ExitWriteLock (); + if (readLocked) + item.rwlock.ExitUpgradeableReadLock (); } } @@ -223,14 +251,18 @@ namespace System.Web.SessionState if (item == null || lockId == null || lockId.GetType() != typeof(Int32) || item.lockId != (Int32)lockId) return; + bool locked = false; try { - item.rwlock.AcquireWriterLock (lockAcquireTimeout); + if (item.rwlock.TryEnterWriteLock (lockAcquireTimeout)) + locked = true; + else + throw new ApplicationException ("Failed to acquire lock"); item.locked = false; } catch { throw; } finally { - if (item.rwlock.IsWriterLockHeld) - item.rwlock.ReleaseWriterLock (); + if (locked) + item.rwlock.ExitWriteLock (); } } @@ -247,14 +279,18 @@ namespace System.Web.SessionState if (inProcItem == null || lockId == null || lockId.GetType() != typeof(Int32) || inProcItem.lockId != (Int32)lockId) return; + bool locked = false; try { - inProcItem.rwlock.AcquireWriterLock (lockAcquireTimeout); + if (inProcItem.rwlock.TryEnterWriteLock (lockAcquireTimeout)) + locked = true; + else + throw new ApplicationException ("Failed to acquire lock after"); cache.Remove (CacheId); } catch { throw; } finally { - if (inProcItem.rwlock.IsWriterLockHeld) - inProcItem.rwlock.ReleaseWriterLock (); + if (locked) + inProcItem.rwlock.ExitWriteLock (); } } @@ -268,16 +304,20 @@ namespace System.Web.SessionState if (item == null) return; + bool locked = false; try { - item.rwlock.AcquireWriterLock (lockAcquireTimeout); + if (item.rwlock.TryEnterWriteLock (lockAcquireTimeout)) + locked = true; + else + throw new ApplicationException ("Failed to acquire lock after"); item.resettingTimeout = true; cache.Remove (CacheId); InsertSessionItem (item, item.timeout, CacheId); } catch { throw; } finally { - if (item.rwlock.IsWriterLockHeld) - item.rwlock.ReleaseWriterLock (); + if (locked) + item.rwlock.ExitWriteLock (); } } @@ -322,9 +362,13 @@ namespace System.Web.SessionState inProcItem.resettingTimeout = true; cache.Remove (CacheId); } - + + bool locked = false; try { - inProcItem.rwlock.AcquireWriterLock (lockAcquireTimeout); + if (inProcItem.rwlock.TryEnterWriteLock (lockAcquireTimeout)) + locked = true; + else + throw new ApplicationException ("Failed to acquire lock"); inProcItem.locked = false; inProcItem.items = itemItems; inProcItem.staticItems = itemStaticItems; @@ -332,8 +376,8 @@ namespace System.Web.SessionState } catch { throw; } finally { - if (inProcItem.rwlock.IsWriterLockHeld) - inProcItem.rwlock.ReleaseWriterLock (); + if (locked) + inProcItem.rwlock.ExitWriteLock (); } } @@ -375,9 +419,11 @@ namespace System.Web.SessionState item.items, item.staticItems, item.timeout)); + item.Dispose (); } else expireCallback (key, null); - } + } else if (value is InProcSessionItem) + ((InProcSessionItem)value).Dispose (); } } } diff --git a/mcs/class/System.Web/System.Web.UI/StateManagedCollection.cs b/mcs/class/System.Web/System.Web.UI/StateManagedCollection.cs index 8d2f6249c93..91cbf2ff100 100644 --- a/mcs/class/System.Web/System.Web.UI/StateManagedCollection.cs +++ b/mcs/class/System.Web/System.Web.UI/StateManagedCollection.cs @@ -112,7 +112,7 @@ namespace System.Web.UI { saveEverything = indices == null; if (saveEverything) { - items.Clear (); + Clear (); for (int i = 0; i < states.Count; i++) { t = types [i]; diff --git a/mcs/class/System.Web/System.Web.dll.sources b/mcs/class/System.Web/System.Web.dll.sources index 151c31a5f97..5476753a5d2 100644 --- a/mcs/class/System.Web/System.Web.dll.sources +++ b/mcs/class/System.Web/System.Web.dll.sources @@ -25,6 +25,7 @@ System.Web.Caching/CachedRawResponse.cs System.Web.Caching/CachedVaryBy.cs System.Web.Caching/DatabaseNotEnabledForNotificationException.cs System.Web.Caching/InMemoryOutputCacheProvider.cs +System.Web.Caching/CacheItemLRU.cs System.Web.Caching/OutputCacheModule.cs System.Web.Caching/OutputCacheProvider.cs System.Web.Caching/SqlCacheDependency.cs diff --git a/mcs/class/System.XML/System.Xml/DefaultXmlWriter.cs b/mcs/class/System.XML/System.Xml/DefaultXmlWriter.cs index e86c340b4d5..db7951b6463 100644 --- a/mcs/class/System.XML/System.Xml/DefaultXmlWriter.cs +++ b/mcs/class/System.XML/System.Xml/DefaultXmlWriter.cs @@ -17,6 +17,7 @@ namespace System.Xml XmlWriter writer; WriteState state = WriteState.Start; bool delegate_write_state; + bool supports_lookup; public DefaultXmlWriter (XmlWriter writer) : this (writer, true) @@ -27,6 +28,7 @@ namespace System.Xml { this.writer = writer; delegate_write_state = delegateWriteState; + supports_lookup = true; } protected XmlWriter Writer { @@ -52,7 +54,16 @@ namespace System.Xml public override string LookupPrefix (string ns) { - return writer.LookupPrefix (ns); + if (!supports_lookup) + return String.Empty; + try { + return writer.LookupPrefix (ns); + } catch (NotSupportedException ex) { + supports_lookup = false; + return String.Empty; + } catch (Exception ex) { + throw; + } } public override void WriteBase64 (byte [] buffer, int index, int count) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/TypeExtensionConverter.cs b/mcs/class/System.Xaml/System.Windows.Markup/TypeExtensionConverter.cs index 0a820dfb1a9..ba95b0242ee 100644 --- a/mcs/class/System.Xaml/System.Windows.Markup/TypeExtensionConverter.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/TypeExtensionConverter.cs @@ -54,13 +54,12 @@ namespace System.Windows.Markup public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { - var vctx = (IValueSerializerContext) context; var tx = value as TypeExtension; - var lookup = vctx != null ? (INamespacePrefixLookup) vctx.GetService (typeof (INamespacePrefixLookup)) : null; - if (tx != null && destinationType == typeof (string)) - return tx.TypeName ?? new XamlTypeName ((XamlType) tx.ProvideValue (vctx)).ToString (lookup); - else + if (!CanConvertTo (context, destinationType) || tx == null) return base.ConvertTo (context, culture, value, destinationType); // it seems it still handles not-supported types (such as int). + var vctx = (IValueSerializerContext) context; + var lookup = vctx != null ? (INamespacePrefixLookup) vctx.GetService (typeof (INamespacePrefixLookup)) : null; + return tx.TypeName ?? new XamlTypeName ((XamlType) tx.ProvideValue (vctx)).ToString (lookup); } } } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs b/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs index 157f0980673..03f49106ce4 100644 --- a/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs @@ -24,8 +24,11 @@ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.Globalization; +using System.Linq; using System.Reflection; using System.Xaml; +using System.Xaml.Schema; namespace System.Windows.Markup { @@ -42,24 +45,63 @@ namespace System.Windows.Markup return GetSerializerFor (type, null); } + // untested public static ValueSerializer GetSerializerFor (PropertyDescriptor descriptor, IValueSerializerContext context) { - throw new NotImplementedException (); + if (descriptor == null) + throw new ArgumentNullException ("descriptor"); + if (context != null) + return context.GetValueSerializerFor (descriptor); + + var tc = descriptor.Converter; + if (tc != null && tc.GetType () != typeof (TypeConverter)) + return new TypeConverterValueSerializer (tc); + return null; } - [MonoTODO ("IValueSerializerContext parameter is not supported")] public static ValueSerializer GetSerializerFor (Type type, IValueSerializerContext context) { if (type == null) throw new ArgumentNullException ("type"); - - // FIXME: it is likely a hack. - if (Type.GetTypeCode (type) != TypeCode.Object) - return new TypeConverterValueSerializer (type); + if (context != null) + return context.GetValueSerializerFor (type); + + // Standard MarkupExtensions are serialized without ValueSerializer. + if (typeof (MarkupExtension).IsAssignableFrom (type) && XamlLanguage.AllTypes.Any (x => x.UnderlyingType == type)) + return null; + + // DateTime is documented as special. + if (type == typeof (DateTime)) + return new DateTimeValueSerializer (); + // String too. + if (type == typeof (string)) + return new StringValueSerializer (); + + // FIXME: this is hack. The complete condition is fully documented at http://msdn.microsoft.com/en-us/library/ms590363.aspx + if (type.GetCustomAttribute (true) != null) { + var tc = TypeDescriptor.GetConverter (type); + if (tc != null && tc.GetType () != typeof (TypeConverter)) + return new TypeConverterValueSerializer (tc); + } + + // Undocumented, but System.Type seems also special. While other MarkupExtension returned types are not handled specially, this method returns a valid instance for System.Type. Note that it doesn't for TypeExtension. + if (type == typeof (Type)) + // Since System.Type does not have a valid TypeConverter, I use TypeExtensionConverter (may sound funny considering the above notes!) for this serializer. + return new TypeValueSerializer (); + + // Undocumented, but several primitive types get a valid serializer while it does not have TypeConverter. + switch (Type.GetTypeCode (type)) { + case TypeCode.Object: + case TypeCode.DBNull: + break; + default: + return new TypeConverterValueSerializer (TypeDescriptor.GetConverter (type)); + } + + // There is still exceptional type! TimeSpan. Why aren't they documented? if (type == typeof (TimeSpan)) - return new TypeConverterValueSerializer (typeof (TimeSpan)); - if (type == typeof (Uri)) - return new TypeConverterValueSerializer (typeof (Uri)); + return new TypeConverterValueSerializer (TypeDescriptor.GetConverter (type)); + return null; } @@ -77,30 +119,32 @@ namespace System.Windows.Markup public virtual object ConvertFromString (string value, IValueSerializerContext context) { - throw new NotSupportedException (String.Format ("Conversion from string '{0}' is not supported", value)); + throw GetConvertFromException (value); } public virtual string ConvertToString (object value, IValueSerializerContext context) { - throw new NotSupportedException (String.Format ("Conversion from '{0}' to string is not supported", value != null ? value.GetType ().Name : "(null)")); + throw GetConvertToException (value, typeof (string)); } protected Exception GetConvertFromException (object value) { - throw new NotImplementedException (); + return new NotSupportedException (String.Format ("Conversion from string '{0}' is not supported", value)); } protected Exception GetConvertToException (object value, Type destinationType) { - throw new NotImplementedException (); + return new NotSupportedException (String.Format ("Conversion from '{0}' to {1} is not supported", value != null ? value.GetType ().Name : "(null)", destinationType)); } public virtual IEnumerable TypeReferences (object value, IValueSerializerContext context) { - throw new NotImplementedException (); + yield break; } } + #region Internal implementations. + internal class StringValueSerializer : ValueSerializer { public override bool CanConvertFromString (string value, IValueSerializerContext context) @@ -115,7 +159,7 @@ namespace System.Windows.Markup public override object ConvertFromString (string value, IValueSerializerContext context) { - throw new NotImplementedException (); + return value; } public override string ConvertToString (object value, IValueSerializerContext context) @@ -129,43 +173,65 @@ namespace System.Windows.Markup } } - #region Internal implementations. - - internal class TypeConverterValueSerializer : TypeConverterValueSerializer + internal class TypeValueSerializer : ValueSerializer { - public TypeConverterValueSerializer () - : base (typeof (T)) + TypeExtensionConverter txc = new TypeExtensionConverter (); + + public override bool CanConvertFromString (string value, IValueSerializerContext context) + { + return true; + } + + public override bool CanConvertToString (object value, IValueSerializerContext context) { + return true; + } + + public override object ConvertFromString (string value, IValueSerializerContext context) + { + var nsr = (IXamlNamespaceResolver) context.GetService (typeof (IXamlNamespaceResolver)); + var scp = (IXamlSchemaContextProvider) context.GetService (typeof (IXamlSchemaContextProvider)); + return scp.SchemaContext.GetXamlType (XamlTypeName.Parse (value, nsr)).UnderlyingType; + } + + public override string ConvertToString (object value, IValueSerializerContext context) + { + return (string) txc.ConvertTo (context, CultureInfo.InvariantCulture, value, typeof (string)); + } + + public override IEnumerable TypeReferences (object value, IValueSerializerContext context) + { + throw new NotImplementedException (); } } internal class TypeConverterValueSerializer : ValueSerializer { - public TypeConverterValueSerializer (Type type) + public TypeConverterValueSerializer (TypeConverter typeConverter) { - c = TypeDescriptor.GetConverter (type); + c = typeConverter; } TypeConverter c; public override bool CanConvertFromString (string value, IValueSerializerContext context) { - return c.CanConvertFrom (typeof (string)); + return c.CanConvertFrom (context, typeof (string)); } public override bool CanConvertToString (object value, IValueSerializerContext context) { - return c.CanConvertTo (typeof (string)); + return c.CanConvertTo (context, typeof (string)); } public override object ConvertFromString (string value, IValueSerializerContext context) { - return c.ConvertFromInvariantString (value); + return c.ConvertFromInvariantString (context, value); } public override string ConvertToString (object value, IValueSerializerContext context) { - return value == null ? String.Empty : c.ConvertToInvariantString (value); + return value == null ? String.Empty : c.ConvertToInvariantString (context, value); } public override IEnumerable TypeReferences (object value, IValueSerializerContext context) diff --git a/mcs/class/System.Xaml/System.Xaml.Schema/XamlTypeTypeConverter.cs b/mcs/class/System.Xaml/System.Xaml.Schema/XamlTypeTypeConverter.cs index d4a435beac3..dc5333ad3f2 100644 --- a/mcs/class/System.Xaml/System.Xaml.Schema/XamlTypeTypeConverter.cs +++ b/mcs/class/System.Xaml/System.Xaml.Schema/XamlTypeTypeConverter.cs @@ -48,6 +48,9 @@ namespace System.Xaml.Schema public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { + if (!CanConvertTo (context, destinationType)) + throw new NotSupportedException (String.Format ("Conversion to type {0} is not supported", destinationType)); + var vctx = (IValueSerializerContext) context; var lookup = vctx != null ? (INamespacePrefixLookup) vctx.GetService (typeof (INamespacePrefixLookup)) : null; var xt = value as XamlType; diff --git a/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs b/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs index 377a4530959..26eb2f03ccb 100644 --- a/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs +++ b/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs @@ -90,37 +90,34 @@ namespace System.Xaml var vs = (xm != null ? xm.ValueSerializer : null) ?? xt.ValueSerializer; if (vs != null) return vs.ConverterInstance.ConvertToString (obj, vsctx); - return (string) ConvertObject (xt, xm, obj, typeof (string), vsctx); - } - - public static object ConvertObject (XamlType xt, XamlMember xm, object target, Type explicitTargetType, IValueSerializerContext vscctx) - { - // First get member value, then convert it to appropriate target type. + // FIXME: does this make sense? var vc = (xm != null ? xm.TypeConverter : null) ?? xt.TypeConverter; var tc = vc != null ? vc.ConverterInstance : null; - if (tc != null && explicitTargetType != null && tc.CanConvertTo (explicitTargetType)) - return tc.ConvertTo (vscctx, CultureInfo.InvariantCulture, target, explicitTargetType); - return target; + if (tc != null && typeof (string) != null && tc.CanConvertTo (vsctx, typeof (string))) + return tc.ConvertToInvariantString (vsctx, obj); + if (obj is string || obj == null) + return (string) obj; + throw new InvalidCastException (String.Format ("Cannot cast object '{0}' to string", obj.GetType ())); } #endregion - public static bool IsContentValue (this XamlMember member) + public static bool IsContentValue (this XamlMember member, IValueSerializerContext vsctx) { if (member == XamlLanguage.Initialization) return true; if (member == XamlLanguage.PositionalParameters) return true; - if (member.TypeConverter != null && member.TypeConverter.ConverterInstance != null) + if (member.TypeConverter != null && member.TypeConverter.ConverterInstance != null && member.TypeConverter.ConverterInstance.CanConvertTo (vsctx, typeof (string))) return true; - return IsContentValue (member.Type); + return IsContentValue (member.Type,vsctx); } - public static bool IsContentValue (this XamlType type) + public static bool IsContentValue (this XamlType type, IValueSerializerContext vsctx) { var t = type.UnderlyingType; - if (type.TypeConverter != null && type.TypeConverter.ConverterInstance != null) + if (type.TypeConverter != null && type.TypeConverter.ConverterInstance != null && type.TypeConverter.ConverterInstance.CanConvertTo (vsctx, typeof (string))) return true; return false; } @@ -139,15 +136,15 @@ namespace System.Xaml return true; } - public static bool HasPositionalParameters (this XamlType type) + public static bool HasPositionalParameters (this XamlType type, IValueSerializerContext vsctx) { // FIXME: find out why only TypeExtension and StaticExtension yield this directive. Seealso XamlObjectReaderTest.Read_CustomMarkupExtension*() return type == XamlLanguage.Type || type == XamlLanguage.Static || - ExaminePositionalParametersApplicable (type) && type.ConstructionRequiresArguments; + ExaminePositionalParametersApplicable (type, vsctx) && type.ConstructionRequiresArguments; } - static bool ExaminePositionalParametersApplicable (this XamlType type) + static bool ExaminePositionalParametersApplicable (this XamlType type, IValueSerializerContext vsctx) { if (!type.IsMarkupExtension || type.UnderlyingType == null) return false; @@ -157,7 +154,7 @@ namespace System.Xaml return false; foreach (var arg in args) - if (arg.Type != null && !arg.Type.IsContentValue ()) + if (arg.Type != null && !arg.Type.IsContentValue (vsctx)) return false; Type [] argTypes = (from arg in args select arg.Type.UnderlyingType).ToArray (); diff --git a/mcs/class/System.Xaml/System.Xaml/XamlLanguage.cs b/mcs/class/System.Xaml/System.Xaml/XamlLanguage.cs index eb334dd6be1..01ed9a838fe 100755 --- a/mcs/class/System.Xaml/System.Xaml/XamlLanguage.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlLanguage.cs @@ -46,13 +46,8 @@ namespace System.Xaml { internal SpecialTypeNameList () { - // FIXME: Extensions can be removed from this list. - Add (new SpecialTypeName ("Array", XamlLanguage.Array)); Add (new SpecialTypeName ("Member", XamlLanguage.Member)); - Add (new SpecialTypeName ("Null", XamlLanguage.Null)); Add (new SpecialTypeName ("Property", XamlLanguage.Property)); - Add (new SpecialTypeName ("Static", XamlLanguage.Static)); - Add (new SpecialTypeName ("Type", XamlLanguage.Type)); } public XamlType Find (string name, string ns) diff --git a/mcs/class/System.Xaml/System.Xaml/XamlMember.cs b/mcs/class/System.Xaml/System.Xaml/XamlMember.cs index f18fb4f0255..ad03cbf6283 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlMember.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlMember.cs @@ -166,11 +166,11 @@ namespace System.Xaml get { return directive_ns ?? (DeclaringType == null ? null : DeclaringType.PreferredXamlNamespace); } } - [MonoTODO] public DesignerSerializationVisibility SerializationVisibility { get { - // FIXME: probably use attribute. - return DesignerSerializationVisibility.Visible; + var c= GetCustomAttributeProvider (); + var a = c == null ? null : c.GetCustomAttribute (false); + return a != null ? a.Visibility : DesignerSerializationVisibility.Visible; } } @@ -310,7 +310,7 @@ namespace System.Xaml protected virtual XamlValueConverter LookupDeferringLoader () { - // FIXME: probably fill from attribute. + // FIXME: use XamlDeferLoadAttribute. return null; } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlNode.cs b/mcs/class/System.Xaml/System.Xaml/XamlNode.cs index 022d3b7b699..a3a52dc0d59 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlNode.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlNode.cs @@ -102,9 +102,9 @@ namespace System.Xaml return type.SchemaContext.GetXamlType (new InstanceContext (obj).GetWrappedValue ().GetType ()); } - public IEnumerable Children () + public IEnumerable Children (IValueSerializerContext vsctx) { - foreach (var xm in type.GetAllObjectReaderMembersByType ()) + foreach (var xm in type.GetAllObjectReaderMembersByType (vsctx)) yield return new XamlNodeMember (this, xm); } @@ -184,9 +184,9 @@ namespace System.Xaml internal static class TypeExtensionMethods2 { // Note that this returns XamlMember which might not actually appear in XamlObjectReader. For example, XamlLanguage.Items won't be returned when there is no item in the collection. - public static IEnumerable GetAllObjectReaderMembersByType (this XamlType type) + public static IEnumerable GetAllObjectReaderMembersByType (this XamlType type, IValueSerializerContext vsctx) { - if (type.HasPositionalParameters ()) { + if (type.HasPositionalParameters (vsctx)) { yield return XamlLanguage.PositionalParameters; yield break; } @@ -196,7 +196,7 @@ namespace System.Xaml if (args != null && args.Any ()) yield return XamlLanguage.Arguments; - if (type.IsContentValue ()) { + if (type.IsContentValue (vsctx)) { yield return XamlLanguage.Initialization; yield break; } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs index 6eb0575d6c7..c18370c5437 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs @@ -112,7 +112,7 @@ namespace System.Xaml if (xm != null) { // overrideMemberType is (so far) used for XamlLanguage.Key. var xtt = overrideMemberType ?? xm.Type; - if (xtt.IsContentValue () || xm.IsContentValue ()) { + if (xtt.IsContentValue (value_serializer_ctx) || xm.IsContentValue (value_serializer_ctx)) { // though null value is special: it is written as a standalone object. var val = xobj.GetRawValue (); if (val == null) @@ -149,7 +149,7 @@ namespace System.Xaml IEnumerable GetObjectMemberNodes (XamlObject xobj) { - var xce = xobj.Children ().GetEnumerator (); + var xce = xobj.Children (value_serializer_ctx).GetEnumerator (); while (xce.MoveNext ()) { // XamlLanguage.Items does not show up if the content is empty. if (xce.Current.Member == XamlLanguage.Items) diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs index 3f39ee8fd10..abc4582d2b7 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs @@ -57,13 +57,14 @@ namespace System.Xaml Stack members = new Stack (); List namespaces; - IServiceProvider service_provider; + IValueSerializerContext service_provider; Stack object_states = new Stack (); class ObjectState { public XamlType Type; public object Value; + public object KeyValue; public List Contents = new List (); public List WrittenProperties = new List (); public bool IsInstantiated; @@ -100,9 +101,9 @@ namespace System.Xaml return; while (object_states.Count > 0) { - WriteEndObject (); - if (object_states.Count > 0) + if (object_states.Count == members.Count) WriteEndMember (); + WriteEndObject (); } } @@ -160,7 +161,11 @@ namespace System.Xaml var state = object_states.Peek (); var contents = state.Contents; - if (xm == XamlLanguage.FactoryMethod) { + if (xm == XamlLanguage.PositionalParameters) { + manager.AcceptMultipleValues = false; + //state.PositionalParameterIndex = -1; + FillConstructedObject (true); + } else if (xm == XamlLanguage.FactoryMethod) { if (contents.Count != 1 || !(contents [0] is string)) throw new XamlObjectWriterException (String.Format ("FactoryMethod must be non-empty string name. {0} value exists.", contents.Count > 0 ? contents [0] : "0")); state.FactoryMethod = (string) contents [0]; @@ -172,7 +177,7 @@ namespace System.Xaml state.Value = mi.Invoke (null, contents.ToArray ()); } else - throw new NotImplementedException (); + FillConstructedObject (false); } else if (xm == XamlLanguage.Initialization) { // ... and no need to do anything. The object value to pop *is* the return value. } else if (xm == XamlLanguage.Items) { @@ -198,13 +203,50 @@ namespace System.Xaml //written_properties_stack.Peek ().Add (xm); } + void FillConstructedObject (bool considerPositionalParameters) + { + var state = object_states.Peek (); + + var args = state.Type.GetSortedConstructorArguments (); + var argt = args != null ? (IList) (from arg in args select arg.Type).ToArray () : considerPositionalParameters ? state.Type.GetPositionalParameters (state.Contents.Count) : null; + + var argv = new object [argt.Count]; + for (int i = 0; i < argv.Length; i++) + argv [i] = GetCorrectlyTypedValue (argt [i], state.Contents [i]); + state.Value = state.Type.Invoker.CreateInstance (argv); + state.IsInstantiated = true; + } + object GetCorrectlyTypedValue (XamlType xt, object value) { + try { + return DoGetCorrectlyTypedValue (xt, value); + } catch (Exception ex) { + // For + ex.Message, the runtime should print InnerException message like .NET does. + throw new XamlObjectWriterException (String.Format ("Could not convert object \'{0}' (of type {1}) to {2}: ", value, value != null ? (object) value.GetType () : "(null)", xt) + ex.Message, ex); + } + } + + // It expects that it is not invoked when there is no value to + // assign. + // When it is passed null, then it returns a default instance. + // For example, passing null as Int32 results in 0. + object DoGetCorrectlyTypedValue (XamlType xt, object value) + { + if (value == null) + return xt.Invoker.CreateInstance (new object [0]); + // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof (Type)) xt = XamlLanguage.Type; if (xt == XamlLanguage.Type && value is string) value = new TypeExtension ((string) value); + + // FIXME: this could be generalized by some means, but I cannot find any. + if (xt.UnderlyingType == typeof (XamlType) && value is string) { + var nsr = (IXamlNamespaceResolver) service_provider.GetService (typeof (IXamlNamespaceResolver)); + value = sctx.GetXamlType (XamlTypeName.Parse ((string) value, nsr)); + } if (value is MarkupExtension) value = ((MarkupExtension) value).ProvideValue (service_provider); @@ -216,8 +258,7 @@ namespace System.Xaml var tc = xt.TypeConverter.ConverterInstance; if (tc != null && tc.CanConvertFrom (value.GetType ())) value = tc.ConvertFrom (value); - if (IsAllowedType (xt, value)) - return value; + return value; } throw new XamlObjectWriterException (String.Format ("Value '{1}' (of type {2}) is not of or convertible to type {0}", xt, value, value != null ? (object) value.GetType () : "(null)")); @@ -282,6 +323,12 @@ namespace System.Xaml throw new ArgumentNullException ("property"); manager.StartMember (); + if (property == XamlLanguage.PositionalParameters) + manager.AcceptMultipleValues = true; + + // FIXME: this condition needs to be examined. What is known to be prevented are: PositionalParameters, Initialization and Base (the last one sort of indicates there's a lot more). + if (!(property is XamlDirective)) + InitializeObjectIfRequired (false); //var wpl = object_states.Peek ().WrittenProperties; // FIXME: enable this. Duplicate property check should @@ -296,12 +343,15 @@ namespace System.Xaml members.Push (property); } - void InitializeObjectIfRequired (bool isStart) + void InitializeObjectIfRequired (bool waitForParameters) { var state = object_states.Peek (); if (state.IsInstantiated) return; + if (waitForParameters && (state.Type.ConstructionRequiresArguments || state.Type.HasPositionalParameters (service_provider))) + return; + // FIXME: "The default techniques in absence of a factory method are to attempt to find a default constructor, then attempt to find an identified type converter on type, member, or destination type." // http://msdn.microsoft.com/en-us/library/system.xaml.xamllanguage.factorymethod%28VS.100%29.aspx object obj; @@ -322,14 +372,14 @@ namespace System.Xaml var xm = members.Count > 0 ? members.Peek () : null; var pstate = xm != null ? object_states.Peek () : null; - var wpl = xm != null && xm != XamlLanguage.Items ? pstate.WrittenProperties : null; + var wpl = xm == null || xm.Type.IsCollection || xm.Type.IsDictionary ? null : pstate.WrittenProperties; if (wpl != null && wpl.Contains (xm)) throw new XamlDuplicateMemberException (String.Format ("Property '{0}' is already set to this '{1}' object", xm, pstate.Type)); var cstate = new ObjectState () {Type = xamlType, IsInstantiated = false}; object_states.Push (cstate); - if (!xamlType.IsContentValue ()) // FIXME: there could be more conditions e.g. the type requires Arguments. + if (!xamlType.IsContentValue (service_provider)) InitializeObjectIfRequired (true); if (wpl != null) // note that this adds to the *owner* object's properties. @@ -347,14 +397,18 @@ namespace System.Xaml if (wpl != null && wpl.Contains (xm)) throw new XamlDuplicateMemberException (String.Format ("Property '{0}' is already set to this '{1}' object", xm, state.Type)); - if (xm == XamlLanguage.Initialization || - xm == state.Type.ContentProperty) { + if (xm == XamlLanguage.Initialization) { value = GetCorrectlyTypedValue (state.Type, value); state.Value = value; state.IsInstantiated = true; } -// else if (xm.Type.IsCollection) - else if (xm == XamlLanguage.Items) // FIXME: am not sure which is good yet. + else if (xm.Type.IsDictionary) { + if (xm == XamlLanguage.Key) + state.KeyValue = GetCorrectlyTypedValue (xm.Type.KeyType, value); + else + state.Contents.Add (GetCorrectlyTypedValue (xm.Type.ItemType, value)); + } + else if (xm.Type.IsCollection) state.Contents.Add (GetCorrectlyTypedValue (xm.Type.ItemType, value)); else state.Contents.Add (GetCorrectlyTypedValue (xm.Type, value)); diff --git a/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs b/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs index 4b4ab9a5397..fd716beb987 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs @@ -216,7 +216,12 @@ namespace System.Xaml bool TypeMatches (XamlType t, string ns, string name, XamlType [] typeArgs) { - return t.PreferredXamlNamespace == ns && t.Name == name && t.TypeArguments.ListEquals (typeArgs); + if (t.PreferredXamlNamespace == ns && t.Name == name && t.TypeArguments.ListEquals (typeArgs)) + return true; + if (t.IsMarkupExtension) + return t.PreferredXamlNamespace == ns && t.Name.Substring (0, t.Name.Length - 9) == name && t.TypeArguments.ListEquals (typeArgs); + else + return false; } protected internal virtual Assembly OnAssemblyResolve (string assemblyName) diff --git a/mcs/class/System.Xaml/System.Xaml/XamlWriterStateManager.cs b/mcs/class/System.Xaml/System.Xaml/XamlWriterStateManager.cs index 81e598738b2..5d147fa0624 100755 --- a/mcs/class/System.Xaml/System.Xaml/XamlWriterStateManager.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlWriterStateManager.cs @@ -118,11 +118,6 @@ namespace System.Xaml bool ns_pushed; bool accept_multiple_values; // It is PositionalParameters-specific state. - // FIXME: remove this: obsoleted. - public bool HasNamespaces { - get { return ns_pushed; } - } - public XamlWriteState State { get { return state; } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs b/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs index be34c1ed527..7bf57a759ee 100755 --- a/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -179,7 +180,7 @@ namespace System.Xaml XamlSchemaContext sctx; XamlWriterStateManager manager; - IValueSerializerContext service_provider; + internal IValueSerializerContext service_provider; internal Stack object_states = new Stack (); internal PrefixLookup prefix_lookup { @@ -213,6 +214,7 @@ namespace System.Xaml public XamlMember Member; public object Value; + public object KeyValue; public AllowedMemberLocations OccuredAs = AllowedMemberLocations.None; } @@ -302,21 +304,7 @@ namespace System.Xaml manager.Value (); - var xm = CurrentMember; - var state = object_states.Peek (); - - if (xm == XamlLanguage.Initialization || - xm == state.Type.ContentProperty) { - value = GetCorrectlyTypedValue (xm, state.Type, value); - state.Value = value; - state.IsInstantiated = true; - } -// else if (xm.Type.IsCollection) - else if (xm == XamlLanguage.Items) // FIXME: am not sure which is good yet. - state.Contents.Add (GetCorrectlyTypedValue (null, xm.Type.ItemType, value)); - else - state.Contents.Add (GetCorrectlyTypedValue (xm, xm.Type, value)); - OnWriteValue (xm, value); + OnWriteValue (value); } public void WriteStartMember (XamlMember property) @@ -357,16 +345,11 @@ namespace System.Xaml var state = object_states.Peek (); if (CurrentMember == XamlLanguage.PositionalParameters) { - // this is an exception that indicates the state manager to accept more than values within this member. manager.AcceptMultipleValues = false; state.PositionalParameterIndex = -1; } - var xm = CurrentMember; var contents = state.Contents; - if (xm == XamlLanguage.PositionalParameters) - state.PositionalParameterIndex = -1; - contents.Clear (); } @@ -380,28 +363,10 @@ namespace System.Xaml protected abstract void OnWriteStartMember (XamlMember xm); - protected abstract void OnWriteValue (XamlMember xm, object value); + protected abstract void OnWriteValue (object value); protected abstract void OnWriteNamespace (NamespaceDeclaration nd); - - void InitializeObjectIfRequired (bool isStart) - { - var state = object_states.Peek (); - if (state.IsInstantiated) - return; - - // FIXME: "The default techniques in absence of a factory method are to attempt to find a default constructor, then attempt to find an identified type converter on type, member, or destination type." - // http://msdn.microsoft.com/en-us/library/system.xaml.xamllanguage.factorymethod%28VS.100%29.aspx - object obj; - if (state.FactoryMethod != null) // FIXME: it must be implemented and verified with tests. - throw new NotImplementedException (); - else - obj = state.Type.Invoker.CreateInstance (null); - state.Value = obj; - state.IsInstantiated = true; - } - bool IsAllowedType (XamlType xt, object value) { // FIXME: not sure if it is correct @@ -414,32 +379,6 @@ namespace System.Xaml value == null && xt == XamlLanguage.Null || xt.IsMarkupExtension && IsAllowedType (xt.MarkupExtensionReturnType, value); } - - object GetCorrectlyTypedValue (XamlMember xm, XamlType xt, object value) - { - // FIXME: this could be generalized by some means, but I cannot find any. - if (xt.UnderlyingType == typeof (Type)) - xt = XamlLanguage.Type; - if (xt == XamlLanguage.Type && value is string) - value = new TypeExtension ((string) value); - - if (value is MarkupExtension) - value = ((MarkupExtension) value).ProvideValue (service_provider); - - if (IsAllowedType (xt, value)) - return value; - - var vc = xm.TypeConverter ?? xt.TypeConverter; - if (vc != null && vc.ConverterInstance != null && value != null) { - var tc = vc.ConverterInstance; - if (tc != null && tc.CanConvertFrom (value.GetType ())) - value = tc.ConvertFrom (value); - if (IsAllowedType (xt, value)) - return value; - } - - throw new XamlObjectWriterException (String.Format ("Value '{1}' (of type {2}) is not of or convertible to type {0}", xt, value, value != null ? (object) value.GetType () : "(null)")); - } protected string GetValueString (XamlMember xm, object value) { @@ -603,7 +542,7 @@ namespace System.Xaml // the second constructor argument. // (Here "top-level" means an object that involves // StartObject i.e. the root or a collection item.) - var posprms = member == XamlLanguage.PositionalParameters && IsAtTopLevelObject () && object_states.Peek ().Type.HasPositionalParameters () ? state.Type.GetSortedConstructorArguments ().GetEnumerator () : null; + var posprms = member == XamlLanguage.PositionalParameters && IsAtTopLevelObject () && object_states.Peek ().Type.HasPositionalParameters (service_provider) ? state.Type.GetSortedConstructorArguments ().GetEnumerator () : null; if (posprms != null) { posprms.MoveNext (); var arg = posprms.Current; @@ -657,7 +596,7 @@ namespace System.Xaml if (xm == XamlLanguage.Initialization) return AllowedMemberLocations.MemberElement; - if (mt.HasPositionalParameters ()) + if (mt.HasPositionalParameters (service_provider)) return AllowedMemberLocations.Attribute; if (w.WriteState == WriteState.Content) return AllowedMemberLocations.MemberElement; @@ -676,7 +615,7 @@ namespace System.Xaml if (xd == null && !xt.GetAllMembers ().Contains (xm)) return AllowedMemberLocations.None; - if (xm.IsContentValue () || xt.IsContentValue ()) + if (xm.IsContentValue (service_provider) || xt.IsContentValue (service_provider)) return AllowedMemberLocations.Attribute; return AllowedMemberLocations.MemberElement; @@ -703,8 +642,9 @@ namespace System.Xaml } } - protected override void OnWriteValue (XamlMember xm, object value) + protected override void OnWriteValue (object value) { + XamlMember xm = CurrentMember; WritePendingStartMember (XamlNodeType.Value); if (w.WriteState != WriteState.Attribute) @@ -748,21 +688,6 @@ namespace System.Xaml local_nss.AddRange (local_nss2); local_nss2.Clear (); } - - string ToMarkupString (XamlType xt, MarkupExtension m) - { - StringBuilder sb = new StringBuilder (); - sb.Append ('{'); - sb.Append (new XamlTypeName (xt).ToString (prefix_lookup)); - foreach (var xm in xt.GetConstructorArguments ()) { - sb.Append (' ').Append (xm.Name).Append ('='); - // FIXME: incomplete - sb.Append (xm.Invoker.GetValue (m)); - } - sb.Append ('}'); - - return sb.ToString (); - } } #if DOTNET diff --git a/mcs/class/System.Xaml/System.Xaml_test.dll.sources b/mcs/class/System.Xaml/System.Xaml_test.dll.sources index a2242d58997..4bc27f70c9f 100644 --- a/mcs/class/System.Xaml/System.Xaml_test.dll.sources +++ b/mcs/class/System.Xaml/System.Xaml_test.dll.sources @@ -12,6 +12,7 @@ System.Xaml.Schema/XamlTypeTypeConverterTest.cs System.Xaml.Schema/XamlValueConverterTest.cs System.Xaml/AmbientPropertyValueTest.cs System.Xaml/AttachableMemberIdentifierTest.cs +System.Xaml/DummyValueSerializerContext.cs System.Xaml/NamespaceDeclarationTest.cs System.Xaml/TestedTypes.cs System.Xaml/XamlDirectiveTest.cs diff --git a/mcs/class/System.Xaml/Test/System.Windows.Markup/TypeExtensionConverterTest.cs b/mcs/class/System.Xaml/Test/System.Windows.Markup/TypeExtensionConverterTest.cs index f7d7a13439f..a4dad5e6132 100644 --- a/mcs/class/System.Xaml/Test/System.Windows.Markup/TypeExtensionConverterTest.cs +++ b/mcs/class/System.Xaml/Test/System.Windows.Markup/TypeExtensionConverterTest.cs @@ -30,6 +30,7 @@ using System.Windows.Markup; using System.Xaml; using System.Xaml.Schema; using NUnit.Framework; +using MonoTests.System.Xaml; using Category = NUnit.Framework.CategoryAttribute; @@ -122,7 +123,15 @@ namespace MonoTests.System.Windows.Markup public void ConvertToFail2 () { var tc = XamlLanguage.Type.TypeConverter.ConverterInstance; - tc.ConvertTo (null, null, "x:Int32", typeof (TypeExtension)); + tc.ConvertTo (new DummyValueSerializerContext (), null, "x:Int32", typeof (TypeExtension)); + } + + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void ConvertToFail3 () + { + var tc = XamlLanguage.Type.TypeConverter.ConverterInstance; + tc.ConvertTo (new DummyValueSerializerContext (), null, "x:Int32", typeof (TypeExtension)); } } } diff --git a/mcs/class/System.Xaml/Test/System.Windows.Markup/ValueSerializerTest.cs b/mcs/class/System.Xaml/Test/System.Windows.Markup/ValueSerializerTest.cs index a88cbd92931..3db68f92c0e 100644 --- a/mcs/class/System.Xaml/Test/System.Windows.Markup/ValueSerializerTest.cs +++ b/mcs/class/System.Xaml/Test/System.Windows.Markup/ValueSerializerTest.cs @@ -31,6 +31,7 @@ using System.Windows.Markup; using System.Xaml; using System.Xaml.Schema; using NUnit.Framework; +using MonoTests.System.Xaml; using Category = NUnit.Framework.CategoryAttribute; @@ -77,6 +78,8 @@ namespace MonoTests.System.Windows.Markup Assert.IsNull (v, "NoSerializer_" + t.Name); continue; } + else if (v == null) + Assert.Fail ("Missing serializer for " + t.Name); // String ValueSerializer is the only exceptional one that mostly fails ConvertToString(). // For remaining types, ConvertToString() should succeed. @@ -101,6 +104,26 @@ namespace MonoTests.System.Windows.Markup } } + [Test] + public void GetSerializerFor () + { + Assert.IsNull (ValueSerializer.GetSerializerFor (typeof (Array)), "#1"); + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (Uri)), "#2"); + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (Type)), "#3"); // has no TypeConverter (undocumented behavior) + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (string)), "#4"); // documented as special + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (DateTime)), "#5"); // documented as special + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (bool)), "#6"); // has no TypeConverter (undocumented behavior) + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (byte)), "#7"); // has no TypeConverter (undocumented behavior) + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (char)), "#8"); // has no TypeConverter (undocumented behavior) + Assert.IsNull (ValueSerializer.GetSerializerFor (typeof (DBNull)), "#9"); // TypeCode.DBNull + Assert.IsNull (ValueSerializer.GetSerializerFor (typeof (object)), "#10"); + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (TimeSpan)), "#11"); // has no TypeConverter (undocumented behavior), TypeCode.Object -> unexpectedly has non-null serializer! + Assert.IsNull (ValueSerializer.GetSerializerFor (typeof (DateTimeOffset)), "#12"); // has no TypeConverter (undocumented behavior), TypeCode.Object -> expected + Assert.IsNull (ValueSerializer.GetSerializerFor (typeof (MyExtension)), "#13"); + Assert.IsNotNull (ValueSerializer.GetSerializerFor (typeof (MyExtension4)), "#14"); // has TypeConverter. + Assert.IsNull (ValueSerializer.GetSerializerFor (typeof (XamlType)), "#15"); // While there is XamlTypeTypeConverter, it is not used on XamlType. + } + [Test] public void DefaultImplementation () { @@ -127,10 +150,23 @@ namespace MonoTests.System.Windows.Markup } catch (NotSupportedException) { } } + + Assert.AreEqual (typeof (NotSupportedException), v.CallGetConvertFromException (null).GetType (), "#1"); + Assert.AreEqual (typeof (NotSupportedException), v.CallGetConvertToException (null, typeof (int)).GetType (), "#2"); + Assert.IsFalse (v.TypeReferences (null, null).GetEnumerator ().MoveNext (), "#3"); } class MyValueSerializer : ValueSerializer { + public Exception CallGetConvertFromException (object value) + { + return GetConvertFromException (value); + } + + public Exception CallGetConvertToException (object value, Type destinationType) + { + return GetConvertToException (value, destinationType); + } } } } diff --git a/mcs/class/System.Xaml/Test/System.Xaml.Schema/XamlTypeTypeConverterTest.cs b/mcs/class/System.Xaml/Test/System.Xaml.Schema/XamlTypeTypeConverterTest.cs index bffd20eb37d..95642d2bc44 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml.Schema/XamlTypeTypeConverterTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml.Schema/XamlTypeTypeConverterTest.cs @@ -41,13 +41,13 @@ namespace MonoTests.System.Xaml.Schema XamlSchemaContext sctx = new XamlSchemaContext (null, null); [Test] - [Ignore ("It should return True for XamlType")] public void CanConvertFrom () { Assert.IsFalse (c.CanConvertFrom (null, typeof (XamlType)), "#1"); Assert.IsTrue (c.CanConvertFrom (null, typeof (string)), "#2"); Assert.IsFalse (c.CanConvertFrom (null, typeof (int)), "#3"); Assert.IsFalse (c.CanConvertFrom (null, typeof (object)), "#4"); + Assert.IsFalse (c.CanConvertFrom (new DummyValueSerializerContext (), typeof (XamlType)), "#5"); } [Test] @@ -57,6 +57,7 @@ namespace MonoTests.System.Xaml.Schema Assert.IsTrue (c.CanConvertTo (null, typeof (string)), "#2"); Assert.IsFalse (c.CanConvertTo (null, typeof (int)), "#3"); Assert.IsFalse (c.CanConvertTo (null, typeof (object)), "#4"); + Assert.IsFalse (c.CanConvertTo (new DummyValueSerializerContext (), typeof (XamlType)), "#5"); } // ConvertFrom() is not supported in either way. @@ -82,6 +83,13 @@ namespace MonoTests.System.Xaml.Schema Assert.AreEqual ("", c.ConvertTo (null, null, XamlLanguage.String, typeof (XamlType)), "#1"); } + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void ConvertXamlTypeToXamlType2 () + { + Assert.AreEqual ("", c.ConvertTo (new DummyValueSerializerContext (), null, XamlLanguage.String, typeof (XamlType)), "#1"); + } + [Test] [ExpectedException (typeof (NotSupportedException))] public void ConvertXamlTypeToType () @@ -109,5 +117,12 @@ namespace MonoTests.System.Xaml.Schema { Assert.AreEqual ("5", c.ConvertTo (null, null, 5, typeof (string)), "#1"); } + + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void ConvertStringToXamlType () + { + Assert.AreEqual ("", c.ConvertTo (new DummyValueSerializerContext (), null, "System.String", typeof (XamlType)), "#1"); + } } } \ No newline at end of file diff --git a/mcs/class/System.Xaml/Test/System.Xaml/DummyValueSerializerContext.cs b/mcs/class/System.Xaml/Test/System.Xaml/DummyValueSerializerContext.cs new file mode 100644 index 00000000000..a555fb48adf --- /dev/null +++ b/mcs/class/System.Xaml/Test/System.Xaml/DummyValueSerializerContext.cs @@ -0,0 +1,74 @@ +// +// Copyright (C) 2010 Novell Inc. http://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.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Windows.Markup; +using System.Xaml; +using System.Xaml.Schema; +using System.Xml; + +namespace MonoTests.System.Xaml +{ + public class DummyValueSerializerContext : IValueSerializerContext + { + public DummyValueSerializerContext () + { + } + + public object GetService (Type serviceType) + { + throw new NotImplementedException (); + } + public IContainer Container { + get { throw new NotImplementedException (); } + } + public object Instance { + get { throw new NotImplementedException (); } + } + public PropertyDescriptor PropertyDescriptor { + get { throw new NotImplementedException (); } + } + public void OnComponentChanged () + { + throw new NotImplementedException (); + } + public bool OnComponentChanging () + { + throw new NotImplementedException (); + } + public ValueSerializer GetValueSerializerFor (PropertyDescriptor descriptor) + { + throw new NotImplementedException (); + } + public ValueSerializer GetValueSerializerFor (Type type) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.Xaml/Test/System.Xaml/TestedTypes.cs b/mcs/class/System.Xaml/Test/System.Xaml/TestedTypes.cs index 11bdd11e9b1..e94c85c04a6 100755 --- a/mcs/class/System.Xaml/Test/System.Xaml/TestedTypes.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/TestedTypes.cs @@ -24,6 +24,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.Globalization; using System.Linq; using System.Reflection; using System.Windows.Markup; @@ -56,6 +57,7 @@ namespace MonoTests.System.Xaml public ComplexPositionalParameterClass Param { get; set; } } + [TypeConverter (typeof (ComplexPositionalParameterClassConverter))] public class ComplexPositionalParameterClass : MarkupExtension { public ComplexPositionalParameterClass (ComplexPositionalParameterValue value) @@ -72,6 +74,25 @@ namespace MonoTests.System.Xaml } } + public class ComplexPositionalParameterClassConverter : TypeConverter + { + public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof (string); + } + + public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object valueToConvert) + { + return new ComplexPositionalParameterClass (new ComplexPositionalParameterValue () {Foo = (string) valueToConvert}); + } + + public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType) + { + // conversion to string is not supported. + return destinationType == typeof (ComplexPositionalParameterClass); + } + } + public class ComplexPositionalParameterValue { public string Foo { get; set; } @@ -394,4 +415,24 @@ namespace MonoTests.System.Xaml { public string Content { get; set; } } + + public class StaticClass1 + { + static StaticClass1 () + { + FooBar = "test"; + } + + public static string FooBar { get; set; } + } + + // FIXME: test it + public class StaticExtensionWrapper + { + public StaticExtensionWrapper () + { + } + + public StaticExtension Param { get; set; } + } } diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs index d4b065cc1ec..cfd8ced1a05 100755 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs @@ -1137,15 +1137,12 @@ namespace MonoTests.System.Xaml Read_CustomMarkupExtension6 (r); } - [Test] // not commonized + [Test] public void Read_ArgumentAttributed () { var obj = new ArgumentAttributed ("foo", "bar"); var r = new XamlObjectReader (obj); - Read_CommonClrType (r, obj, new KeyValuePair ("x", XamlLanguage.Xaml2006Namespace)); - var args = Read_AttributedArguments_String (r, new string [] {"arg1", "arg2"}); - Assert.AreEqual ("foo", args [0], "#1"); - Assert.AreEqual ("bar", args [1], "#2"); + Read_ArgumentAttributed (r, obj); } } @@ -1320,6 +1317,18 @@ namespace MonoTests.System.Xaml Assert.IsFalse (r.Read (), "#9"); } + protected void Read_ArgumentAttributed (XamlReader r, object obj) + { + Read_CommonClrType (r, obj, new KeyValuePair ("x", XamlLanguage.Xaml2006Namespace)); + + if (r is XamlXmlReader) + ReadBase (r); + + var args = Read_AttributedArguments_String (r, new string [] {"arg1", "arg2"}); + Assert.AreEqual ("foo", args [0], "#1"); + Assert.AreEqual ("bar", args [1], "#2"); + } + protected void Read_Dictionary (XamlReader r) { Assert.IsTrue (r.Read (), "ns#1-1"); diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs index 3c6d778684e..ceda7bcca9e 100755 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs @@ -25,10 +25,12 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.IO; +using System.Linq; using System.Reflection; using System.Windows.Markup; using System.Xaml; using System.Xaml.Schema; +using System.Xml; using NUnit.Framework; using CategoryAttribute = NUnit.Framework.CategoryAttribute; @@ -350,8 +352,16 @@ namespace MonoTests.System.Xaml Assert.AreEqual ("bar", l [1], "#3"); } + // I believe .NET XamlObjectWriter.Dispose() is hack and should + // be fixed to exactly determine which of End (member or object) + // to call that results in this ExpectedException. + // Surprisingly, PositionalParameters is allowed to be closed + // without EndMember. So it smells that .NET is hacky. + // We should disable this test and introduce better code (which + // is already in XamlWriterInternalBase). [Test] [ExpectedException (typeof (XamlObjectWriterException))] + [Ignore ("See the comment in XamlObjectWriterTest.cs")] public void CloseWithoutEndMember () { var xw = new XamlObjectWriter (sctx, null); @@ -682,5 +692,399 @@ namespace MonoTests.System.Xaml xw.WriteGetObject (); xw.WriteEndObject (); } + + // extra use case based tests. + + [Test] + public void WriteEx_Type_WriteString () + { + var ow = new XamlObjectWriter (sctx); + ow.WriteNamespace (new NamespaceDeclaration (XamlLanguage.Xaml2006Namespace, "x" + )); + ow.WriteStartObject (XamlLanguage.Type); + ow.WriteStartMember (XamlLanguage.PositionalParameters); + ow.WriteValue ("x:Int32"); + ow.Close (); + Assert.AreEqual (typeof (int), ow.Result, "#1"); + } + + [Test] + public void WriteEx_Type_WriteType () + { + var ow = new XamlObjectWriter (sctx); + ow.WriteNamespace (new NamespaceDeclaration (XamlLanguage.Xaml2006Namespace, "x" + )); + ow.WriteStartObject (XamlLanguage.Type); + ow.WriteStartMember (XamlLanguage.PositionalParameters); + ow.WriteValue (typeof (int)); + ow.Close (); + Assert.AreEqual (typeof (int), ow.Result, "#1"); + } + + // common use case based tests (to other readers/writers). + + XamlReader GetReader (string filename) + { + return new XamlXmlReader (XmlReader.Create (Path.Combine ("Test/XmlFiles", filename), new XmlReaderSettings () { CloseInput =true })); + } + + [Test] + public void Write_String () + { + using (var xr = GetReader ("String.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual ("foo", des, "#1"); + } + } + + [Test] + public void Write_Int32 () + { + using (var xr = GetReader ("Int32.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (5, des, "#1"); + } + } + + [Test] + public void Write_DateTime () + { + using (var xr = GetReader ("DateTime.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (new DateTime (2010, 4, 14), des, "#1"); + } + } + + [Test] + public void Write_TimeSpan () + { + using (var xr = GetReader ("TimeSpan.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (TimeSpan.FromMinutes (7), des, "#1"); + } + } + + [Test] + public void Write_Uri () + { + using (var xr = GetReader ("Uri.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (new Uri ("urn:foo"), des, "#1"); + } + } + + [Test] + public void Write_Null () + { + using (var xr = GetReader ("NullExtension.xml")) { + var des = XamlServices.Load (xr); + Assert.IsNull (des, "#1"); + } + } + + [Test] + public void Write_Type () + { + using (var xr = GetReader ("Type.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (typeof (int), des, "#1"); + } + } + + [Test] + public void Write_Type2 () + { + var obj = typeof (MonoTests.System.Xaml.TestClass1); + using (var xr = GetReader ("Type2.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + public void Write_Guid () + { + var obj = Guid.Parse ("9c3345ec-8922-4662-8e8d-a4e41f47cf09"); + using (var xr = GetReader ("Guid.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + [ExpectedException (typeof (XamlObjectWriterException))] // cannot resolve the StaticExtension value. + [Category ("NotWorking")] + public void Write_StaticExtension () + { + var obj = new StaticExtension ("FooBar"); + using (var xr = GetReader ("StaticExtension.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + [Ignore ("Not sure why MemberType is NOT serialized. Needs investigation")] + public void Write_StaticExtension2 () + { + var obj = new StaticExtension ("FooBar"); //incorrect + using (var xr = GetReader ("StaticExtension2.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + public void Write_Reference () + { + using (var xr = GetReader ("Reference.xml")) { + var des = XamlServices.Load (xr); + // .NET does not return Reference. + // Its ProvideValue() returns MS.Internal.Xaml.Context.NameFixupToken, + // which is assumed (by name) to resolve to the referenced object. + Assert.IsNotNull (des, "#1"); + //Assert.AreEqual (new Reference ("FooBar"), des, "#1"); + } + } + + [Test] + public void Write_ArrayInt32 () + { + var obj = new int [] {4, -5, 0, 255, int.MaxValue}; + using (var xr = GetReader ("Array_Int32.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + public void Write_ListInt32 () + { + var obj = new int [] {5, -3, int.MaxValue, 0}.ToList (); + using (var xr = GetReader ("List_Int32.xml")) { + var des = (List) XamlServices.Load (xr); + Assert.AreEqual (obj.ToArray (), des.ToArray (), "#1"); + } + } + + [Test] + public void Write_ListInt32_2 () + { + var obj = new List (new int [0]) { Capacity = 0 }; // set explicit capacity for trivial implementation difference + using (var xr = GetReader ("List_Int32_2.xml")) { + var des = (List) XamlServices.Load (xr); + Assert.AreEqual (obj.ToArray (), des.ToArray (), "#1"); + } + } + + [Test] + public void Write_ListType () + { + var obj = new List (new Type [] {typeof (int), typeof (Dictionary)}) { Capacity = 2 }; + using (var xr = GetReader ("List_Type.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + [Category ("NotWorking")] + public void Write_DictionaryInt32String () + { + var dic = new Dictionary (); + dic.Add (0, "foo"); + dic.Add (5, "bar"); + dic.Add (-2, "baz"); + using (var xr = GetReader ("Dictionary_Int32_String.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (dic, des, "#1"); + } + } + + [Test] + [Category ("NotWorking")] + public void Write_DictionaryStringType () + { + var dic = new Dictionary (); + dic.Add ("t1", typeof (int)); + dic.Add ("t2", typeof (int [])); + dic.Add ("t3", typeof (int?)); + dic.Add ("t4", typeof (List)); + dic.Add ("t5", typeof (Dictionary)); + dic.Add ("t6", typeof (List>)); + using (var xr = GetReader ("Dictionary_String_Type.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (dic, des, "#1"); + } + } + + [Test] + [Ignore ("Needs to get successfully deserialized. Currently we can't")] + public void Write_PositionalParameters1Wrapper () + { + // Unlike the above case, this has the wrapper object and hence PositionalParametersClass1 can be written as an attribute (markup extension) + var obj = new PositionalParametersWrapper ("foo", 5); + using (var xr = GetReader ("PositionalParametersWrapper.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + public void Write_ArgumentAttributed () + { + //var obj = new ArgumentAttributed ("foo", "bar"); + using (var xr = GetReader ("ArgumentAttributed.xml")) { + var des = (ArgumentAttributed) XamlServices.Load (xr); + Assert.AreEqual ("foo", des.Arg1, "#1"); + Assert.AreEqual ("bar", des.Arg2, "#2"); + } + } + + [Test] + public void Write_ArrayExtension2 () + { + //var obj = new ArrayExtension (typeof (int)); + using (var xr = GetReader ("ArrayExtension2.xml")) { + var des = XamlServices.Load (xr); + // The resulting object is not ArrayExtension. + Assert.AreEqual (new int [0], des, "#1"); + } + } + + [Test] + public void Write_ArrayList () + { + var obj = new ArrayList (new int [] {5, -3, 0}); + using (var xr = GetReader ("ArrayList.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + [Ignore ("Needs to get successfully deserialized. Currently we can't")] + public void ComplexPositionalParameterWrapper () + { + //var obj = new ComplexPositionalParameterWrapper () { Param = new ComplexPositionalParameterClass (new ComplexPositionalParameterValue () { Foo = "foo" })}; + using (var xr = GetReader ("ComplexPositionalParameterWrapper.xml")) { + var des = (ComplexPositionalParameterWrapper) XamlServices.Load (xr); + Assert.IsNotNull (des.Param, "#1"); + Assert.AreEqual ("foo", des.Param.Value, "#2"); + } + } + + [Test] + public void Write_ListWrapper () + { + var obj = new ListWrapper (new List (new int [] {5, -3, 0}) { Capacity = 3}); // set explicit capacity for trivial implementation difference + using (var xr = GetReader ("ListWrapper.xml")) { + var des = (ListWrapper) XamlServices.Load (xr); + Assert.IsNotNull (des, "#1"); + Assert.IsNotNull (des.Items, "#2"); + Assert.AreEqual (obj.Items.ToArray (), des.Items.ToArray (), "#3"); + } + } + + [Test] + public void Write_ListWrapper2 () + { + var obj = new ListWrapper2 (new List (new int [] {5, -3, 0}) { Capacity = 3}); // set explicit capacity for trivial implementation difference + using (var xr = GetReader ("ListWrapper2.xml")) { + var des = (ListWrapper2) XamlServices.Load (xr); + Assert.IsNotNull (des, "#1"); + Assert.IsNotNull (des.Items, "#2"); + Assert.AreEqual (obj.Items.ToArray (), des.Items.ToArray (), "#3"); + } + } + + [Test] + public void Write_MyArrayExtension () + { + //var obj = new MyArrayExtension (new int [] {5, -3, 0}); + using (var xr = GetReader ("MyArrayExtension.xml")) { + var des = XamlServices.Load (xr); + // ProvideValue() returns an array + Assert.AreEqual (new int [] {5, -3, 0}, des, "#1"); + } + } + + [Test] + public void Write_MyArrayExtensionA () + { + //var obj = new MyArrayExtensionA (new int [] {5, -3, 0}); + using (var xr = GetReader ("MyArrayExtensionA.xml")) { + var des = XamlServices.Load (xr); + // ProvideValue() returns an array + Assert.AreEqual (new int [] {5, -3, 0}, des, "#1"); + } + } + + [Test] + public void Write_MyExtension () + { + //var obj = new MyExtension () { Foo = typeof (int), Bar = "v2", Baz = "v7"}; + using (var xr = GetReader ("MyExtension.xml")) { + var des = XamlServices.Load (xr); + // ProvideValue() returns this. + Assert.AreEqual ("provided_value", des, "#1"); + } + } + + [Test] + [ExpectedException (typeof (InvalidCastException))] // unable to cast string to MarkupExtension + [Category ("NotWorking")] + public void Write_MyExtension2 () + { + //var obj = new MyExtension2 () { Foo = typeof (int), Bar = "v2"}; + using (var xr = GetReader ("MyExtension2.xml")) { + XamlServices.Load (xr); + } + } + + [Test] + public void Write_MyExtension3 () + { + //var obj = new MyExtension3 () { Foo = typeof (int), Bar = "v2"}; + using (var xr = GetReader ("MyExtension3.xml")) { + var des = XamlServices.Load (xr); + // StringConverter is used and the resulting value comes from ToString(). + Assert.AreEqual ("MonoTests.System.Xaml.MyExtension3", des, "#1"); + } + } + + [Test] + [ExpectedException (typeof (XamlObjectWriterException))] // wrong TypeConverter input (input string for DateTimeConverter invalid) + public void Write_MyExtension4 () + { + var obj = new MyExtension4 () { Foo = typeof (int), Bar = "v2"}; + using (var xr = GetReader ("MyExtension4.xml")) { + var des = XamlServices.Load (xr); + Assert.AreEqual (obj, des, "#1"); + } + } + + [Test] + public void Write_MyExtension6 () + { + //var obj = new MyExtension6 ("foo"); + using (var xr = GetReader ("MyExtension6.xml")) { + var des = XamlServices.Load (xr); + // ProvideValue() returns this. + Assert.AreEqual ("foo", des, "#1"); + } + } + + [Test] + public void Write_PropertyDefinition () + { + //var obj = new PropertyDefinition () { Modifier = "protected", Name = "foo", Type = XamlLanguage.String }; + using (var xr = GetReader ("PropertyDefinition.xml")) { + var des = (PropertyDefinition) XamlServices.Load (xr); + Assert.AreEqual ("protected", des.Modifier, "#1"); + Assert.AreEqual ("foo", des.Name, "#2"); + Assert.AreEqual (XamlLanguage.String, des.Type, "#3"); + } + } } } diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs index c3d18bf1c94..8cf9b36634c 100755 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs @@ -438,6 +438,14 @@ namespace MonoTests.System.Xaml Read_CustomMarkupExtension6 (r); } + [Test] + public void Read_ArgumentAttributed () + { + var obj = new ArgumentAttributed ("foo", "bar"); + var r = GetReader ("ArgumentAttributed.xml"); + Read_ArgumentAttributed (r, obj); + } + [Test] public void Read_Dictionary () { diff --git a/mcs/class/System.Xaml/Test/XmlFiles/StaticExtension2.xml b/mcs/class/System.Xaml/Test/XmlFiles/StaticExtension2.xml new file mode 100644 index 00000000000..1acb64b253d --- /dev/null +++ b/mcs/class/System.Xaml/Test/XmlFiles/StaticExtension2.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mcs/class/corlib/System.Collections.Concurrent.Partitioners/ListPartitioner.cs b/mcs/class/corlib/System.Collections.Concurrent.Partitioners/ListPartitioner.cs index 9d975651c7b..b107faf8e0d 100644 --- a/mcs/class/corlib/System.Collections.Concurrent.Partitioners/ListPartitioner.cs +++ b/mcs/class/corlib/System.Collections.Concurrent.Partitioners/ListPartitioner.cs @@ -60,7 +60,7 @@ namespace System.Collections.Concurrent.Partitioners enumerators[i] = GetEnumeratorForRange (i * step, enumerators.Length, source.Count, step); continue; } - + if (i != enumerators.Length - 1) enumerators[i] = GetEnumeratorForRange (i * count, i * count + count); else @@ -97,7 +97,7 @@ namespace System.Collections.Concurrent.Partitioners yield return new KeyValuePair (i, source[i]); } } - + IEnumerator> GetEnumeratorForRangeInternal (int startIndex, int stride, int count, int step) { for (int i = startIndex; i < count; i += stride * step) { diff --git a/mcs/class/corlib/System.Collections.Concurrent/OrderablePartitioner.cs b/mcs/class/corlib/System.Collections.Concurrent/OrderablePartitioner.cs index 9b2c8a41281..8b2ca20c303 100644 --- a/mcs/class/corlib/System.Collections.Concurrent/OrderablePartitioner.cs +++ b/mcs/class/corlib/System.Collections.Concurrent/OrderablePartitioner.cs @@ -59,10 +59,11 @@ namespace System.Collections.Concurrent = GetOrderablePartitions (partitionCount); for (int i = 0; i < enumerators.Count; i++) - temp[i] = GetProxyEnumerator (enumerators[i]); + temp[i] = new ProxyEnumerator (enumerators[i]); return temp; } + IEnumerator GetProxyEnumerator (IEnumerator> enumerator) { @@ -80,7 +81,6 @@ namespace System.Collections.Concurrent return null; } - public bool KeysOrderedInEachPartition { get { return keysOrderedInEachPartition; @@ -98,6 +98,47 @@ namespace System.Collections.Concurrent return keysNormalized; } } + + class ProxyEnumerator : IEnumerator, IDisposable + { + IEnumerator> internalEnumerator; + + internal ProxyEnumerator (IEnumerator> enumerator) + { + internalEnumerator = enumerator; + } + + public void Dispose () + { + internalEnumerator.Dispose (); + } + + public bool MoveNext () + { + if (!internalEnumerator.MoveNext ()) + return false; + + Current = internalEnumerator.Current.Value; + + return true; + } + + public void Reset () + { + internalEnumerator.Reset (); + } + + object IEnumerator.Current { + get { + return Current; + } + } + + public TSource Current { + get; + private set; + } + } } } #endif diff --git a/mcs/class/corlib/System.Threading.Tasks/Scheduler.cs b/mcs/class/corlib/System.Threading.Tasks/Scheduler.cs index bb7be9d1c89..d83c212d01c 100644 --- a/mcs/class/corlib/System.Threading.Tasks/Scheduler.cs +++ b/mcs/class/corlib/System.Threading.Tasks/Scheduler.cs @@ -30,23 +30,23 @@ namespace System.Threading.Tasks { internal class Scheduler: TaskScheduler, IScheduler { - IProducerConsumerCollection workQueue; - ThreadWorker[] workers; - EventWaitHandle pulseHandle = new AutoResetEvent (false); + readonly IProducerConsumerCollection workQueue; + readonly ThreadWorker[] workers; + readonly EventWaitHandle pulseHandle = new AutoResetEvent (false); public Scheduler () - : this (Environment.ProcessorCount, 0, ThreadPriority.Normal) + : this (Environment.ProcessorCount, ThreadPriority.AboveNormal) { } - public Scheduler (int maxWorker, int maxStackSize, ThreadPriority priority) + public Scheduler (int maxWorker, ThreadPriority priority) { workQueue = new ConcurrentQueue (); workers = new ThreadWorker [maxWorker]; for (int i = 0; i < maxWorker; i++) { - workers [i] = new ThreadWorker (this, workers, workQueue, maxStackSize, priority, pulseHandle); + workers [i] = new ThreadWorker (this, workers, i, workQueue, priority, pulseHandle); workers [i].Pulse (); } } @@ -64,9 +64,7 @@ namespace System.Threading.Tasks if (AreTasksFinished (task)) return; - ParticipateUntil (delegate { - return AreTasksFinished (task); - }); + ParticipateUntil (() => AreTasksFinished (task)); } public bool ParticipateUntil (Task task, Func predicate) @@ -101,9 +99,8 @@ namespace System.Threading.Tasks public void Dispose () { - foreach (ThreadWorker w in workers) { + foreach (ThreadWorker w in workers) w.Dispose (); - } } bool AreTasksFinished (Task parent) diff --git a/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs b/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs index 73ef7d63262..ac9ee851f3f 100644 --- a/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs +++ b/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs @@ -31,98 +31,75 @@ namespace System.Threading.Tasks { internal class ThreadWorker : IDisposable { - static Random r = new Random (); - Thread workerThread; - readonly ThreadWorker[] others; - internal readonly IDequeOperations dDeque; - readonly Action childWorkAdder; - readonly EventWaitHandle waitHandle; - readonly IProducerConsumerCollection sharedWorkQueue; + readonly IDequeOperations dDeque; + readonly ThreadWorker[] others; + readonly EventWaitHandle waitHandle; + readonly IProducerConsumerCollection sharedWorkQueue; + readonly IScheduler sched; + readonly ThreadPriority threadPriority; + // Flag to tell if workerThread is running int started = 0; - readonly bool isLocal; readonly int workerLength; - readonly int stealingStart; + readonly int workerPosition; const int maxRetry = 5; const int sleepThreshold = 100; const int deepSleepTime = 10; - Action threadInitializer; - - public ThreadWorker (IScheduler sched, ThreadWorker[] others, IProducerConsumerCollection sharedWorkQueue, - int maxStackSize, ThreadPriority priority, EventWaitHandle handle) - : this (sched, others, sharedWorkQueue, true, maxStackSize, priority, handle) - { - } - - public ThreadWorker (IScheduler sched, ThreadWorker[] others, IProducerConsumerCollection sharedWorkQueue, - bool createThread, int maxStackSize, ThreadPriority priority, EventWaitHandle handle) + public ThreadWorker (IScheduler sched, + ThreadWorker[] others, + int workerPosition, + IProducerConsumerCollection sharedWorkQueue, + ThreadPriority priority, + EventWaitHandle handle) { this.others = others; - - this.dDeque = new CyclicDeque (); - + this.dDeque = new CyclicDeque (); + this.sched = sched; this.sharedWorkQueue = sharedWorkQueue; this.workerLength = others.Length; - this.isLocal = !createThread; + this.workerPosition = workerPosition; this.waitHandle = handle; - - this.childWorkAdder = delegate (Task t) { - dDeque.PushBottom (t); - sched.PulseAll (); - }; - - // Find the stealing start index randomly (then the traversal - // will be done in Round-Robin fashion) - do { - this.stealingStart = r.Next(0, workerLength); - } while (others[stealingStart] == this); - - InitializeUnderlyingThread (maxStackSize, priority); + this.threadPriority = priority; + + InitializeUnderlyingThread (); } - void InitializeUnderlyingThread (int maxStackSize, ThreadPriority priority) + void InitializeUnderlyingThread () { - threadInitializer = delegate { - // Special case of the participant ThreadWorker - if (isLocal) { - this.workerThread = Thread.CurrentThread; - return; - } - - this.workerThread = (maxStackSize == 0) ? new Thread (WorkerMethodWrapper) : - new Thread (WorkerMethodWrapper, maxStackSize); + this.workerThread = new Thread (WorkerMethodWrapper); - this.workerThread.IsBackground = true; - this.workerThread.Priority = priority; - this.workerThread.Name = "ParallelFxThreadWorker"; - }; - threadInitializer (); + this.workerThread.IsBackground = true; + this.workerThread.Priority = threadPriority; + this.workerThread.Name = "ParallelFxThreadWorker"; } public void Dispose () { Stop (); - if (!isLocal && workerThread.ThreadState != ThreadState.Stopped) + if (workerThread.ThreadState != ThreadState.Stopped) workerThread.Abort (); } public void Pulse () { + if (started == 1) + return; + // If the thread was stopped then set it in use and restart it int result = Interlocked.Exchange (ref started, 1); if (result != 0) return; - if (!isLocal) { - if (this.workerThread.ThreadState != ThreadState.Unstarted) { - threadInitializer (); - } - workerThread.Start (); + + if (this.workerThread.ThreadState != ThreadState.Unstarted) { + InitializeUnderlyingThread (); } + + workerThread.Start (); } public void Stop () @@ -179,7 +156,7 @@ namespace System.Threading.Tasks // Now we process our work while (dDeque.PopBottom (out value) == PopResult.Succeed) { if (value != null) { - value.Execute (childWorkAdder); + value.Execute (ChildWorkAdder); result = true; } } @@ -189,9 +166,10 @@ namespace System.Threading.Tasks ThreadWorker other; // Repeat the operation a little so that we can let other things process. - for (int j = 0; j < maxRetry; j++) { + for (int j = 0; j < maxRetry; ++j) { + int len = workerLength + workerPosition; // Start stealing with the ThreadWorker at our right to minimize contention - for (int it = stealingStart; it < stealingStart + workerLength; it++) { + for (int it = workerPosition + 1; it < len; ++it) { int i = it % workerLength; if ((other = others [i]) == null || other == this) continue; @@ -200,7 +178,7 @@ namespace System.Threading.Tasks if (other.dDeque.PopTop (out value) == PopResult.Succeed) { hasStolenFromOther = true; if (value != null) { - value.Execute (childWorkAdder); + value.Execute (ChildWorkAdder); result = true; } } @@ -260,6 +238,12 @@ namespace System.Threading.Tasks wait.SpinOnce (); } } + + internal void ChildWorkAdder (Task t) + { + dDeque.PushBottom (t); + sched.PulseAll (); + } static bool CheckTaskFitness (Task t) { @@ -271,13 +255,7 @@ namespace System.Threading.Tasks return started == 0; } } - - public bool IsLocal { - get { - return isLocal; - } - } - + public int Id { get { return workerThread.ManagedThreadId; diff --git a/mcs/class/corlib/System.Threading/CancellationToken.cs b/mcs/class/corlib/System.Threading/CancellationToken.cs index 51fb2dc8d62..f541e770b54 100644 --- a/mcs/class/corlib/System.Threading/CancellationToken.cs +++ b/mcs/class/corlib/System.Threading/CancellationToken.cs @@ -73,7 +73,8 @@ namespace System.Threading public void ThrowIfCancellationRequested () { - Source.ThrowIfCancellationRequested (); + if (Source.IsCancellationRequested) + throw new OperationCanceledException (this); } public bool Equals (CancellationToken other) diff --git a/mcs/class/corlib/System.Threading/CancellationTokenSource.cs b/mcs/class/corlib/System.Threading/CancellationTokenSource.cs index 12f59a5d190..05ca53a182f 100644 --- a/mcs/class/corlib/System.Threading/CancellationTokenSource.cs +++ b/mcs/class/corlib/System.Threading/CancellationTokenSource.cs @@ -33,8 +33,8 @@ namespace System.Threading public sealed class CancellationTokenSource : IDisposable { - volatile bool canceled; - volatile bool processed; + bool canceled; + bool processed; int currId = int.MinValue; @@ -76,6 +76,7 @@ namespace System.Threading } } + Thread.MemoryBarrier (); processed = true; if (exceptions != null && exceptions.Count > 0) @@ -155,13 +156,7 @@ namespace System.Threading sw.SpinOnce (); } - - internal void ThrowIfCancellationRequested () - { - if (canceled) - throw new OperationCanceledException (CreateToken ()); - } - + CancellationTokenRegistration GetTokenReg () { CancellationTokenRegistration registration diff --git a/mcs/mcs/argument.cs b/mcs/mcs/argument.cs index 604bbbb5e0b..d578e3532b9 100644 --- a/mcs/mcs/argument.cs +++ b/mcs/mcs/argument.cs @@ -10,7 +10,6 @@ // using System; -using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; diff --git a/mcs/mcs/assembly.cs b/mcs/mcs/assembly.cs new file mode 100644 index 00000000000..f636e786a40 --- /dev/null +++ b/mcs/mcs/assembly.cs @@ -0,0 +1,657 @@ +// +// assembly.cs: Assembly declaration and specifications +// +// Authors: +// Miguel de Icaza (miguel@ximian.com) +// Marek Safar (marek.safar@gmail.com) +// +// Copyright 2001, 2002, 2003 Ximian, Inc. +// Copyright 2004 Novell, Inc. +// + + +using System; +using System.IO; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Reflection.Emit; +using System.Security; +using System.Security.Cryptography; +using System.Security.Permissions; + +using Mono.Security.Cryptography; + +namespace Mono.CSharp { + + public abstract class CommonAssemblyModulClass : Attributable, IMemberContext + { + public void AddAttributes (List attrs, IMemberContext context) + { + foreach (Attribute a in attrs) + a.AttachTo (this, context); + + if (attributes == null) { + attributes = new Attributes (attrs); + return; + } + attributes.AddAttributes (attrs); + } + + public virtual void Emit (TypeContainer tc) + { + if (OptAttributes == null) + return; + + OptAttributes.Emit (); + } + + protected Attribute ResolveAttribute (PredefinedAttribute a_type) + { + Attribute a = OptAttributes.Search (a_type); + if (a != null) { + a.Resolve (); + } + return a; + } + + #region IMemberContext Members + + public CompilerContext Compiler { + get { return RootContext.ToplevelTypes.Compiler; } + } + + public TypeSpec CurrentType { + get { return null; } + } + + public TypeParameter[] CurrentTypeParameters { + get { return null; } + } + + public MemberCore CurrentMemberDefinition { + get { return RootContext.ToplevelTypes; } + } + + public string GetSignatureForError () + { + return ""; + } + + public bool HasUnresolvedConstraints { + get { return false; } + } + + public bool IsObsolete { + get { return false; } + } + + public bool IsUnsafe { + get { return false; } + } + + public bool IsStatic { + get { return false; } + } + + public IList LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope) + { + throw new NotImplementedException (); + } + + public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104) + { + return RootContext.ToplevelTypes.LookupNamespaceOrType (name, arity, loc, ignore_cs0104); + } + + public FullNamedExpression LookupNamespaceAlias (string name) + { + return null; + } + + #endregion + } + + public class AssemblyClass : CommonAssemblyModulClass { + // TODO: make it private and move all builder based methods here + public AssemblyBuilder Builder; + bool is_cls_compliant; + bool wrap_non_exception_throws; + + public Attribute ClsCompliantAttribute; + + Dictionary declarative_security; + bool has_extension_method; + public AssemblyName Name; + MethodInfo add_type_forwarder; + Dictionary emitted_forwarders; + + // Module is here just because of error messages + static string[] attribute_targets = new string [] { "assembly", "module" }; + + public AssemblyClass () + { + wrap_non_exception_throws = true; + } + + public bool HasExtensionMethods { + set { + has_extension_method = value; + } + } + + public bool IsClsCompliant { + get { + return is_cls_compliant; + } + } + + public bool WrapNonExceptionThrows { + get { + return wrap_non_exception_throws; + } + } + + public override AttributeTargets AttributeTargets { + get { + return AttributeTargets.Assembly; + } + } + + public override bool IsClsComplianceRequired () + { + return is_cls_compliant; + } + + Report Report { + get { return Compiler.Report; } + } + + public void Resolve () + { + if (RootContext.Unsafe) { + // + // Emits [assembly: SecurityPermissionAttribute (SecurityAction.RequestMinimum, SkipVerification = true)] + // when -unsafe option was specified + // + + Location loc = Location.Null; + + MemberAccess system_security_permissions = new MemberAccess (new MemberAccess ( + new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Security", loc), "Permissions", loc); + + Arguments pos = new Arguments (1); + pos.Add (new Argument (new MemberAccess (new MemberAccess (system_security_permissions, "SecurityAction", loc), "RequestMinimum"))); + + Arguments named = new Arguments (1); + named.Add (new NamedArgument ("SkipVerification", loc, new BoolLiteral (true, loc))); + + GlobalAttribute g = new GlobalAttribute (new NamespaceEntry (Compiler, null, null, null), "assembly", + new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"), + new Arguments[] { pos, named }, loc, false); + g.AttachTo (this, this); + + if (g.Resolve () != null) { + declarative_security = new Dictionary (); + g.ExtractSecurityPermissionSet (declarative_security); + } + } + + if (OptAttributes == null) + return; + + // Ensure that we only have GlobalAttributes, since the Search isn't safe with other types. + if (!OptAttributes.CheckTargets()) + return; + + ClsCompliantAttribute = ResolveAttribute (Compiler.PredefinedAttributes.CLSCompliant); + + if (ClsCompliantAttribute != null) { + is_cls_compliant = ClsCompliantAttribute.GetClsCompliantAttributeValue (); + } + + Attribute a = ResolveAttribute (Compiler.PredefinedAttributes.RuntimeCompatibility); + if (a != null) { + var val = a.GetPropertyValue ("WrapNonExceptionThrows") as BoolConstant; + if (val != null) + wrap_non_exception_throws = val.Value; + } + } + + // fix bug #56621 + private void SetPublicKey (AssemblyName an, byte[] strongNameBlob) + { + try { + // check for possible ECMA key + if (strongNameBlob.Length == 16) { + // will be rejected if not "the" ECMA key + an.SetPublicKey (strongNameBlob); + } + else { + // take it, with or without, a private key + RSA rsa = CryptoConvert.FromCapiKeyBlob (strongNameBlob); + // and make sure we only feed the public part to Sys.Ref + byte[] publickey = CryptoConvert.ToCapiPublicKeyBlob (rsa); + + // AssemblyName.SetPublicKey requires an additional header + byte[] publicKeyHeader = new byte [12] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00 }; + + byte[] encodedPublicKey = new byte [12 + publickey.Length]; + Buffer.BlockCopy (publicKeyHeader, 0, encodedPublicKey, 0, 12); + Buffer.BlockCopy (publickey, 0, encodedPublicKey, 12, publickey.Length); + an.SetPublicKey (encodedPublicKey); + } + } + catch (Exception) { + Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' is incorrectly encoded"); + Environment.Exit (1); + } + } + + void Error_ObsoleteSecurityAttribute (Attribute a, string option) + { + Report.Warning (1699, 1, a.Location, + "Use compiler option `{0}' or appropriate project settings instead of `{1}' attribute", + option, a.Name); + } + + // TODO: rewrite this code (to kill N bugs and make it faster) and use standard ApplyAttribute way. + public AssemblyName GetAssemblyName (string name, string output) + { + if (OptAttributes != null) { + foreach (Attribute a in OptAttributes.Attrs) { + // cannot rely on any resolve-based members before you call Resolve + if (a.ExplicitTarget == null || a.ExplicitTarget != "assembly") + continue; + + // TODO: This code is buggy: comparing Attribute name without resolving is wrong. + // However, this is invoked by CodeGen.Init, when none of the namespaces + // are loaded yet. + // TODO: Does not handle quoted attributes properly + switch (a.Name) { + case "AssemblyKeyFile": + case "AssemblyKeyFileAttribute": + case "System.Reflection.AssemblyKeyFileAttribute": + if (RootContext.StrongNameKeyFile != null) { + Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ()); + Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", + "keyfile", "System.Reflection.AssemblyKeyFileAttribute"); + } else { + string value = a.GetString (); + if (!string.IsNullOrEmpty (value)) { + Error_ObsoleteSecurityAttribute (a, "keyfile"); + RootContext.StrongNameKeyFile = value; + } + } + break; + case "AssemblyKeyName": + case "AssemblyKeyNameAttribute": + case "System.Reflection.AssemblyKeyNameAttribute": + if (RootContext.StrongNameKeyContainer != null) { + Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ()); + Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", + "keycontainer", "System.Reflection.AssemblyKeyNameAttribute"); + } else { + string value = a.GetString (); + if (!string.IsNullOrEmpty (value)) { + Error_ObsoleteSecurityAttribute (a, "keycontainer"); + RootContext.StrongNameKeyContainer = value; + } + } + break; + case "AssemblyDelaySign": + case "AssemblyDelaySignAttribute": + case "System.Reflection.AssemblyDelaySignAttribute": + bool b = a.GetBoolean (); + if (b) { + Error_ObsoleteSecurityAttribute (a, "delaysign"); + } + + RootContext.StrongNameDelaySign = b; + break; + } + } + } + + AssemblyName an = new AssemblyName (); + an.Name = Path.GetFileNameWithoutExtension (name); + + // note: delay doesn't apply when using a key container + if (RootContext.StrongNameKeyContainer != null) { + an.KeyPair = new StrongNameKeyPair (RootContext.StrongNameKeyContainer); + return an; + } + + // strongname is optional + if (RootContext.StrongNameKeyFile == null) + return an; + + string AssemblyDir = Path.GetDirectoryName (output); + + // the StrongName key file may be relative to (a) the compiled + // file or (b) to the output assembly. See bugzilla #55320 + // http://bugzilla.ximian.com/show_bug.cgi?id=55320 + + // (a) relative to the compiled file + string filename = Path.GetFullPath (RootContext.StrongNameKeyFile); + bool exist = File.Exists (filename); + if ((!exist) && (AssemblyDir != null) && (AssemblyDir != String.Empty)) { + // (b) relative to the outputed assembly + filename = Path.GetFullPath (Path.Combine (AssemblyDir, RootContext.StrongNameKeyFile)); + exist = File.Exists (filename); + } + + if (exist) { + using (FileStream fs = new FileStream (filename, FileMode.Open, FileAccess.Read)) { + byte[] snkeypair = new byte [fs.Length]; + fs.Read (snkeypair, 0, snkeypair.Length); + + if (RootContext.StrongNameDelaySign) { + // delayed signing - DO NOT include private key + SetPublicKey (an, snkeypair); + } + else { + // no delay so we make sure we have the private key + try { + CryptoConvert.FromCapiPrivateKeyBlob (snkeypair); + an.KeyPair = new StrongNameKeyPair (snkeypair); + } + catch (CryptographicException) { + if (snkeypair.Length == 16) { + // error # is different for ECMA key + Report.Error (1606, "Could not sign the assembly. " + + "ECMA key can only be used to delay-sign assemblies"); + } + else { + Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' does not have a private key"); + } + return null; + } + } + } + } + else { + Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' does not exist"); + return null; + } + return an; + } + + void Error_AssemblySigning (string text) + { + Report.Error (1548, "Error during assembly signing. " + text); + } + + bool CheckInternalsVisibleAttribute (Attribute a) + { + string assembly_name = a.GetString (); + if (assembly_name.Length == 0) + return false; + + AssemblyName aname = null; + try { + aname = new AssemblyName (assembly_name); + } catch (FileLoadException) { + } catch (ArgumentException) { + } + + // Bad assembly name format + if (aname == null) + Report.Warning (1700, 3, a.Location, "Assembly reference `" + assembly_name + "' is invalid and cannot be resolved"); + // Report error if we have defined Version or Culture + else if (aname.Version != null || aname.CultureInfo != null) + throw new Exception ("Friend assembly `" + a.GetString () + + "' is invalid. InternalsVisibleTo cannot have version or culture specified."); + else if (aname.GetPublicKey () == null && Name.GetPublicKey () != null && Name.GetPublicKey ().Length != 0) { + Report.Error (1726, a.Location, "Friend assembly reference `" + aname.FullName + "' is invalid." + + " Strong named assemblies must specify a public key in their InternalsVisibleTo declarations"); + return false; + } + + return true; + } + + static string IsValidAssemblyVersion (string version) + { + Version v; + try { + v = new Version (version); + } catch { + try { + int major = int.Parse (version, CultureInfo.InvariantCulture); + v = new Version (major, 0); + } catch { + return null; + } + } + + foreach (int candidate in new int [] { v.Major, v.Minor, v.Build, v.Revision }) { + if (candidate > ushort.MaxValue) + return null; + } + + return new Version (v.Major, System.Math.Max (0, v.Minor), System.Math.Max (0, v.Build), System.Math.Max (0, v.Revision)).ToString (4); + } + + public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) + { + if (a.IsValidSecurityAttribute ()) { + if (declarative_security == null) + declarative_security = new Dictionary (); + + a.ExtractSecurityPermissionSet (declarative_security); + return; + } + + if (a.Type == pa.AssemblyCulture) { + string value = a.GetString (); + if (value == null || value.Length == 0) + return; + + if (RootContext.Target == Target.Exe) { + a.Error_AttributeEmitError ("The executables cannot be satelite assemblies, remove the attribute or keep it empty"); + return; + } + + try { + var fi = typeof (AssemblyBuilder).GetField ("culture", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); + fi.SetValue (Builder, value == "neutral" ? "" : value); + } catch { + Report.RuntimeMissingSupport (a.Location, "AssemblyCultureAttribute setting"); + } + + return; + } + + if (a.Type == pa.AssemblyVersion) { + string value = a.GetString (); + if (value == null || value.Length == 0) + return; + + var vinfo = IsValidAssemblyVersion (value.Replace ('*', '0')); + if (vinfo == null) { + a.Error_AttributeEmitError (string.Format ("Specified version `{0}' is not valid", value)); + return; + } + + try { + var fi = typeof (AssemblyBuilder).GetField ("version", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); + fi.SetValue (Builder, vinfo); + } catch { + Report.RuntimeMissingSupport (a.Location, "AssemblyVersionAttribute setting"); + } + + return; + } + + if (a.Type == pa.AssemblyAlgorithmId) { + const int pos = 2; // skip CA header + uint alg = (uint) cdata [pos]; + alg |= ((uint) cdata [pos + 1]) << 8; + alg |= ((uint) cdata [pos + 2]) << 16; + alg |= ((uint) cdata [pos + 3]) << 24; + + try { + var fi = typeof (AssemblyBuilder).GetField ("algid", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); + fi.SetValue (Builder, alg); + } catch { + Report.RuntimeMissingSupport (a.Location, "AssemblyAlgorithmIdAttribute setting"); + } + + return; + } + + if (a.Type == pa.AssemblyFlags) { + const int pos = 2; // skip CA header + uint flags = (uint) cdata[pos]; + flags |= ((uint) cdata[pos + 1]) << 8; + flags |= ((uint) cdata[pos + 2]) << 16; + flags |= ((uint) cdata[pos + 3]) << 24; + + // Ignore set PublicKey flag if assembly is not strongnamed + if ((flags & (uint) AssemblyNameFlags.PublicKey) != 0 && (Builder.GetName ().KeyPair == null)) + flags &= ~(uint)AssemblyNameFlags.PublicKey; + + try { + var fi = typeof (AssemblyBuilder).GetField ("flags", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); + fi.SetValue (Builder, flags); + } catch { + Report.RuntimeMissingSupport (a.Location, "AssemblyFlagsAttribute setting"); + } + + return; + } + + if (a.Type == pa.InternalsVisibleTo && !CheckInternalsVisibleAttribute (a)) + return; + + if (a.Type == pa.TypeForwarder) { + TypeSpec t = a.GetArgumentType (); + if (t == null || TypeManager.HasElementType (t)) { + Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute"); + return; + } + + if (emitted_forwarders == null) { + emitted_forwarders = new Dictionary (); + } else if (emitted_forwarders.ContainsKey (t.MemberDefinition)) { + Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null); + Report.Error(739, a.Location, "A duplicate type forward of type `{0}'", + TypeManager.CSharpName(t)); + return; + } + + emitted_forwarders.Add(t.MemberDefinition, a); + + if (t.Assembly == Builder) { + Report.SymbolRelatedToPreviousError (t); + Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly", + TypeManager.CSharpName (t)); + return; + } + + if (t.IsNested) { + Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type", + TypeManager.CSharpName (t)); + return; + } + + if (add_type_forwarder == null) { + add_type_forwarder = typeof (AssemblyBuilder).GetMethod ("AddTypeForwarder", + BindingFlags.NonPublic | BindingFlags.Instance); + + if (add_type_forwarder == null) { + Report.RuntimeMissingSupport (a.Location, "TypeForwardedTo attribute"); + return; + } + } + + add_type_forwarder.Invoke (Builder, new object[] { t.GetMetaInfo () }); + return; + } + + if (a.Type == pa.Extension) { + a.Error_MisusedExtensionAttribute (); + return; + } + + Builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); + } + + public override void Emit (TypeContainer tc) + { + base.Emit (tc); + + if (has_extension_method) + Compiler.PredefinedAttributes.Extension.EmitAttribute (Builder); + + PredefinedAttribute pa = tc.Compiler.PredefinedAttributes.RuntimeCompatibility; + if (pa.IsDefined && (OptAttributes == null || !OptAttributes.Contains (pa))) { + var ci = TypeManager.GetPredefinedConstructor (pa.Type, Location.Null, TypeSpec.EmptyTypes); + PropertyInfo [] pis = new PropertyInfo [1]; + + pis [0] = TypeManager.GetPredefinedProperty (pa.Type, + "WrapNonExceptionThrows", Location.Null, TypeManager.bool_type).MetaInfo; + object [] pargs = new object [1]; + pargs [0] = true; + Builder.SetCustomAttribute (new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0], pis, pargs)); + } + + if (declarative_security != null) { + + MethodInfo add_permission = typeof (AssemblyBuilder).GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic); + object builder_instance = Builder; + + try { + // Microsoft runtime hacking + if (add_permission == null) { + var assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData"); + add_permission = assembly_builder.GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic); + + FieldInfo fi = typeof (AssemblyBuilder).GetField ("m_assemblyData", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField); + builder_instance = fi.GetValue (Builder); + } + + var args = new PermissionSet [3]; + declarative_security.TryGetValue (SecurityAction.RequestMinimum, out args [0]); + declarative_security.TryGetValue (SecurityAction.RequestOptional, out args [1]); + declarative_security.TryGetValue (SecurityAction.RequestRefuse, out args [2]); + add_permission.Invoke (builder_instance, args); + } + catch { + Report.RuntimeMissingSupport (Location.Null, "assembly permission setting"); + } + } + } + + public override string[] ValidAttributeTargets { + get { + return attribute_targets; + } + } + + // Wrapper for AssemblyBuilder.AddModule + static MethodInfo adder_method; + static public MethodInfo AddModule_Method { + get { + if (adder_method == null) + adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic); + return adder_method; + } + } + public Module AddModule (string module) + { + MethodInfo m = AddModule_Method; + if (m == null) { + Report.RuntimeMissingSupport (Location.Null, "/addmodule"); + Environment.Exit (1); + } + + try { + return (Module) m.Invoke (Builder, new object [] { module }); + } catch (TargetInvocationException ex) { + throw ex.InnerException; + } + } + } +} diff --git a/mcs/mcs/assign.cs b/mcs/mcs/assign.cs index 0f8c64ec508..2463b09a411 100644 --- a/mcs/mcs/assign.cs +++ b/mcs/mcs/assign.cs @@ -12,7 +12,6 @@ // Copyright 2004-2008 Novell, Inc // using System; -using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs index 40ccd4857d0..cb705c4b2e5 100644 --- a/mcs/mcs/codegen.cs +++ b/mcs/mcs/codegen.cs @@ -1,34 +1,20 @@ // // codegen.cs: The code generator // -// Author: +// Authors: // Miguel de Icaza (miguel@ximian.com) +// Marek Safar (marek.safar@gmail.com) // // Copyright 2001, 2002, 2003 Ximian, Inc. // Copyright 2004 Novell, Inc. // -// -// Please leave this defined on SVN: The idea is that when we ship the -// compiler to end users, if the compiler crashes, they have a chance -// to narrow down the problem. -// -// Only remove it if you need to debug locally on your tree. -// -//#define PRODUCTION - using System; -using System.IO; using System.Collections.Generic; -using System.Globalization; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; -using System.Security; using System.Security.Cryptography; -using System.Security.Permissions; - -using Mono.Security.Cryptography; namespace Mono.CSharp { @@ -299,7 +285,7 @@ namespace Mono.CSharp { this.return_type = return_type; } -#region Properties + #region Properties public TypeSpec CurrentType { get { return MemberContext.CurrentType; } @@ -844,635 +830,4 @@ namespace Mono.CSharp { return return_value; } } - - public abstract class CommonAssemblyModulClass : Attributable, IMemberContext - { - public void AddAttributes (List attrs, IMemberContext context) - { - foreach (Attribute a in attrs) - a.AttachTo (this, context); - - if (attributes == null) { - attributes = new Attributes (attrs); - return; - } - attributes.AddAttributes (attrs); - } - - public virtual void Emit (TypeContainer tc) - { - if (OptAttributes == null) - return; - - OptAttributes.Emit (); - } - - protected Attribute ResolveAttribute (PredefinedAttribute a_type) - { - Attribute a = OptAttributes.Search (a_type); - if (a != null) { - a.Resolve (); - } - return a; - } - - #region IMemberContext Members - - public CompilerContext Compiler { - get { return RootContext.ToplevelTypes.Compiler; } - } - - public TypeSpec CurrentType { - get { return null; } - } - - public TypeParameter[] CurrentTypeParameters { - get { return null; } - } - - public MemberCore CurrentMemberDefinition { - get { return RootContext.ToplevelTypes; } - } - - public string GetSignatureForError () - { - return ""; - } - - public bool HasUnresolvedConstraints { - get { return false; } - } - - public bool IsObsolete { - get { return false; } - } - - public bool IsUnsafe { - get { return false; } - } - - public bool IsStatic { - get { return false; } - } - - public IList LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope) - { - throw new NotImplementedException (); - } - - public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104) - { - return RootContext.ToplevelTypes.LookupNamespaceOrType (name, arity, loc, ignore_cs0104); - } - - public FullNamedExpression LookupNamespaceAlias (string name) - { - return null; - } - - #endregion - } - - public class AssemblyClass : CommonAssemblyModulClass { - // TODO: make it private and move all builder based methods here - public AssemblyBuilder Builder; - bool is_cls_compliant; - bool wrap_non_exception_throws; - - public Attribute ClsCompliantAttribute; - - Dictionary declarative_security; - bool has_extension_method; - public AssemblyName Name; - MethodInfo add_type_forwarder; - Dictionary emitted_forwarders; - - // Module is here just because of error messages - static string[] attribute_targets = new string [] { "assembly", "module" }; - - public AssemblyClass () - { - wrap_non_exception_throws = true; - } - - public bool HasExtensionMethods { - set { - has_extension_method = value; - } - } - - public bool IsClsCompliant { - get { - return is_cls_compliant; - } - } - - public bool WrapNonExceptionThrows { - get { - return wrap_non_exception_throws; - } - } - - public override AttributeTargets AttributeTargets { - get { - return AttributeTargets.Assembly; - } - } - - public override bool IsClsComplianceRequired () - { - return is_cls_compliant; - } - - Report Report { - get { return Compiler.Report; } - } - - public void Resolve () - { - if (RootContext.Unsafe) { - // - // Emits [assembly: SecurityPermissionAttribute (SecurityAction.RequestMinimum, SkipVerification = true)] - // when -unsafe option was specified - // - - Location loc = Location.Null; - - MemberAccess system_security_permissions = new MemberAccess (new MemberAccess ( - new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Security", loc), "Permissions", loc); - - Arguments pos = new Arguments (1); - pos.Add (new Argument (new MemberAccess (new MemberAccess (system_security_permissions, "SecurityAction", loc), "RequestMinimum"))); - - Arguments named = new Arguments (1); - named.Add (new NamedArgument ("SkipVerification", loc, new BoolLiteral (true, loc))); - - GlobalAttribute g = new GlobalAttribute (new NamespaceEntry (Compiler, null, null, null), "assembly", - new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"), - new Arguments[] { pos, named }, loc, false); - g.AttachTo (this, this); - - if (g.Resolve () != null) { - declarative_security = new Dictionary (); - g.ExtractSecurityPermissionSet (declarative_security); - } - } - - if (OptAttributes == null) - return; - - // Ensure that we only have GlobalAttributes, since the Search isn't safe with other types. - if (!OptAttributes.CheckTargets()) - return; - - ClsCompliantAttribute = ResolveAttribute (Compiler.PredefinedAttributes.CLSCompliant); - - if (ClsCompliantAttribute != null) { - is_cls_compliant = ClsCompliantAttribute.GetClsCompliantAttributeValue (); - } - - Attribute a = ResolveAttribute (Compiler.PredefinedAttributes.RuntimeCompatibility); - if (a != null) { - var val = a.GetPropertyValue ("WrapNonExceptionThrows") as BoolConstant; - if (val != null) - wrap_non_exception_throws = val.Value; - } - } - - // fix bug #56621 - private void SetPublicKey (AssemblyName an, byte[] strongNameBlob) - { - try { - // check for possible ECMA key - if (strongNameBlob.Length == 16) { - // will be rejected if not "the" ECMA key - an.SetPublicKey (strongNameBlob); - } - else { - // take it, with or without, a private key - RSA rsa = CryptoConvert.FromCapiKeyBlob (strongNameBlob); - // and make sure we only feed the public part to Sys.Ref - byte[] publickey = CryptoConvert.ToCapiPublicKeyBlob (rsa); - - // AssemblyName.SetPublicKey requires an additional header - byte[] publicKeyHeader = new byte [12] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00 }; - - byte[] encodedPublicKey = new byte [12 + publickey.Length]; - Buffer.BlockCopy (publicKeyHeader, 0, encodedPublicKey, 0, 12); - Buffer.BlockCopy (publickey, 0, encodedPublicKey, 12, publickey.Length); - an.SetPublicKey (encodedPublicKey); - } - } - catch (Exception) { - Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' is incorrectly encoded"); - Environment.Exit (1); - } - } - - void Error_ObsoleteSecurityAttribute (Attribute a, string option) - { - Report.Warning (1699, 1, a.Location, - "Use compiler option `{0}' or appropriate project settings instead of `{1}' attribute", - option, a.Name); - } - - // TODO: rewrite this code (to kill N bugs and make it faster) and use standard ApplyAttribute way. - public AssemblyName GetAssemblyName (string name, string output) - { - if (OptAttributes != null) { - foreach (Attribute a in OptAttributes.Attrs) { - // cannot rely on any resolve-based members before you call Resolve - if (a.ExplicitTarget == null || a.ExplicitTarget != "assembly") - continue; - - // TODO: This code is buggy: comparing Attribute name without resolving is wrong. - // However, this is invoked by CodeGen.Init, when none of the namespaces - // are loaded yet. - // TODO: Does not handle quoted attributes properly - switch (a.Name) { - case "AssemblyKeyFile": - case "AssemblyKeyFileAttribute": - case "System.Reflection.AssemblyKeyFileAttribute": - if (RootContext.StrongNameKeyFile != null) { - Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ()); - Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", - "keyfile", "System.Reflection.AssemblyKeyFileAttribute"); - } else { - string value = a.GetString (); - if (!string.IsNullOrEmpty (value)) { - Error_ObsoleteSecurityAttribute (a, "keyfile"); - RootContext.StrongNameKeyFile = value; - } - } - break; - case "AssemblyKeyName": - case "AssemblyKeyNameAttribute": - case "System.Reflection.AssemblyKeyNameAttribute": - if (RootContext.StrongNameKeyContainer != null) { - Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ()); - Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", - "keycontainer", "System.Reflection.AssemblyKeyNameAttribute"); - } else { - string value = a.GetString (); - if (!string.IsNullOrEmpty (value)) { - Error_ObsoleteSecurityAttribute (a, "keycontainer"); - RootContext.StrongNameKeyContainer = value; - } - } - break; - case "AssemblyDelaySign": - case "AssemblyDelaySignAttribute": - case "System.Reflection.AssemblyDelaySignAttribute": - bool b = a.GetBoolean (); - if (b) { - Error_ObsoleteSecurityAttribute (a, "delaysign"); - } - - RootContext.StrongNameDelaySign = b; - break; - } - } - } - - AssemblyName an = new AssemblyName (); - an.Name = Path.GetFileNameWithoutExtension (name); - - // note: delay doesn't apply when using a key container - if (RootContext.StrongNameKeyContainer != null) { - an.KeyPair = new StrongNameKeyPair (RootContext.StrongNameKeyContainer); - return an; - } - - // strongname is optional - if (RootContext.StrongNameKeyFile == null) - return an; - - string AssemblyDir = Path.GetDirectoryName (output); - - // the StrongName key file may be relative to (a) the compiled - // file or (b) to the output assembly. See bugzilla #55320 - // http://bugzilla.ximian.com/show_bug.cgi?id=55320 - - // (a) relative to the compiled file - string filename = Path.GetFullPath (RootContext.StrongNameKeyFile); - bool exist = File.Exists (filename); - if ((!exist) && (AssemblyDir != null) && (AssemblyDir != String.Empty)) { - // (b) relative to the outputed assembly - filename = Path.GetFullPath (Path.Combine (AssemblyDir, RootContext.StrongNameKeyFile)); - exist = File.Exists (filename); - } - - if (exist) { - using (FileStream fs = new FileStream (filename, FileMode.Open, FileAccess.Read)) { - byte[] snkeypair = new byte [fs.Length]; - fs.Read (snkeypair, 0, snkeypair.Length); - - if (RootContext.StrongNameDelaySign) { - // delayed signing - DO NOT include private key - SetPublicKey (an, snkeypair); - } - else { - // no delay so we make sure we have the private key - try { - CryptoConvert.FromCapiPrivateKeyBlob (snkeypair); - an.KeyPair = new StrongNameKeyPair (snkeypair); - } - catch (CryptographicException) { - if (snkeypair.Length == 16) { - // error # is different for ECMA key - Report.Error (1606, "Could not sign the assembly. " + - "ECMA key can only be used to delay-sign assemblies"); - } - else { - Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' does not have a private key"); - } - return null; - } - } - } - } - else { - Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' does not exist"); - return null; - } - return an; - } - - void Error_AssemblySigning (string text) - { - Report.Error (1548, "Error during assembly signing. " + text); - } - - bool CheckInternalsVisibleAttribute (Attribute a) - { - string assembly_name = a.GetString (); - if (assembly_name.Length == 0) - return false; - - AssemblyName aname = null; - try { - aname = new AssemblyName (assembly_name); - } catch (FileLoadException) { - } catch (ArgumentException) { - } - - // Bad assembly name format - if (aname == null) - Report.Warning (1700, 3, a.Location, "Assembly reference `" + assembly_name + "' is invalid and cannot be resolved"); - // Report error if we have defined Version or Culture - else if (aname.Version != null || aname.CultureInfo != null) - throw new Exception ("Friend assembly `" + a.GetString () + - "' is invalid. InternalsVisibleTo cannot have version or culture specified."); - else if (aname.GetPublicKey () == null && Name.GetPublicKey () != null && Name.GetPublicKey ().Length != 0) { - Report.Error (1726, a.Location, "Friend assembly reference `" + aname.FullName + "' is invalid." + - " Strong named assemblies must specify a public key in their InternalsVisibleTo declarations"); - return false; - } - - return true; - } - - static string IsValidAssemblyVersion (string version) - { - Version v; - try { - v = new Version (version); - } catch { - try { - int major = int.Parse (version, CultureInfo.InvariantCulture); - v = new Version (major, 0); - } catch { - return null; - } - } - - foreach (int candidate in new int [] { v.Major, v.Minor, v.Build, v.Revision }) { - if (candidate > ushort.MaxValue) - return null; - } - - return new Version (v.Major, System.Math.Max (0, v.Minor), System.Math.Max (0, v.Build), System.Math.Max (0, v.Revision)).ToString (4); - } - - public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) - { - if (a.IsValidSecurityAttribute ()) { - if (declarative_security == null) - declarative_security = new Dictionary (); - - a.ExtractSecurityPermissionSet (declarative_security); - return; - } - - if (a.Type == pa.AssemblyCulture) { - string value = a.GetString (); - if (value == null || value.Length == 0) - return; - - if (RootContext.Target == Target.Exe) { - a.Error_AttributeEmitError ("The executables cannot be satelite assemblies, remove the attribute or keep it empty"); - return; - } - - try { - var fi = typeof (AssemblyBuilder).GetField ("culture", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); - fi.SetValue (Builder, value == "neutral" ? "" : value); - } catch { - Report.RuntimeMissingSupport (a.Location, "AssemblyCultureAttribute setting"); - } - - return; - } - - if (a.Type == pa.AssemblyVersion) { - string value = a.GetString (); - if (value == null || value.Length == 0) - return; - - var vinfo = IsValidAssemblyVersion (value.Replace ('*', '0')); - if (vinfo == null) { - a.Error_AttributeEmitError (string.Format ("Specified version `{0}' is not valid", value)); - return; - } - - try { - var fi = typeof (AssemblyBuilder).GetField ("version", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); - fi.SetValue (Builder, vinfo); - } catch { - Report.RuntimeMissingSupport (a.Location, "AssemblyVersionAttribute setting"); - } - - return; - } - - if (a.Type == pa.AssemblyAlgorithmId) { - const int pos = 2; // skip CA header - uint alg = (uint) cdata [pos]; - alg |= ((uint) cdata [pos + 1]) << 8; - alg |= ((uint) cdata [pos + 2]) << 16; - alg |= ((uint) cdata [pos + 3]) << 24; - - try { - var fi = typeof (AssemblyBuilder).GetField ("algid", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); - fi.SetValue (Builder, alg); - } catch { - Report.RuntimeMissingSupport (a.Location, "AssemblyAlgorithmIdAttribute setting"); - } - - return; - } - - if (a.Type == pa.AssemblyFlags) { - const int pos = 2; // skip CA header - uint flags = (uint) cdata[pos]; - flags |= ((uint) cdata[pos + 1]) << 8; - flags |= ((uint) cdata[pos + 2]) << 16; - flags |= ((uint) cdata[pos + 3]) << 24; - - // Ignore set PublicKey flag if assembly is not strongnamed - if ((flags & (uint) AssemblyNameFlags.PublicKey) != 0 && (Builder.GetName ().KeyPair == null)) - flags &= ~(uint)AssemblyNameFlags.PublicKey; - - try { - var fi = typeof (AssemblyBuilder).GetField ("flags", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); - fi.SetValue (Builder, flags); - } catch { - Report.RuntimeMissingSupport (a.Location, "AssemblyFlagsAttribute setting"); - } - - return; - } - - if (a.Type == pa.InternalsVisibleTo && !CheckInternalsVisibleAttribute (a)) - return; - - if (a.Type == pa.TypeForwarder) { - TypeSpec t = a.GetArgumentType (); - if (t == null || TypeManager.HasElementType (t)) { - Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute"); - return; - } - - if (emitted_forwarders == null) { - emitted_forwarders = new Dictionary (); - } else if (emitted_forwarders.ContainsKey (t.MemberDefinition)) { - Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null); - Report.Error(739, a.Location, "A duplicate type forward of type `{0}'", - TypeManager.CSharpName(t)); - return; - } - - emitted_forwarders.Add(t.MemberDefinition, a); - - if (t.Assembly == Builder) { - Report.SymbolRelatedToPreviousError (t); - Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly", - TypeManager.CSharpName (t)); - return; - } - - if (t.IsNested) { - Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type", - TypeManager.CSharpName (t)); - return; - } - - if (add_type_forwarder == null) { - add_type_forwarder = typeof (AssemblyBuilder).GetMethod ("AddTypeForwarder", - BindingFlags.NonPublic | BindingFlags.Instance); - - if (add_type_forwarder == null) { - Report.RuntimeMissingSupport (a.Location, "TypeForwardedTo attribute"); - return; - } - } - - add_type_forwarder.Invoke (Builder, new object[] { t.GetMetaInfo () }); - return; - } - - if (a.Type == pa.Extension) { - a.Error_MisusedExtensionAttribute (); - return; - } - - Builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); - } - - public override void Emit (TypeContainer tc) - { - base.Emit (tc); - - if (has_extension_method) - Compiler.PredefinedAttributes.Extension.EmitAttribute (Builder); - - PredefinedAttribute pa = tc.Compiler.PredefinedAttributes.RuntimeCompatibility; - if (pa.IsDefined && (OptAttributes == null || !OptAttributes.Contains (pa))) { - var ci = TypeManager.GetPredefinedConstructor (pa.Type, Location.Null, TypeSpec.EmptyTypes); - PropertyInfo [] pis = new PropertyInfo [1]; - - pis [0] = TypeManager.GetPredefinedProperty (pa.Type, - "WrapNonExceptionThrows", Location.Null, TypeManager.bool_type).MetaInfo; - object [] pargs = new object [1]; - pargs [0] = true; - Builder.SetCustomAttribute (new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0], pis, pargs)); - } - - if (declarative_security != null) { - - MethodInfo add_permission = typeof (AssemblyBuilder).GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic); - object builder_instance = Builder; - - try { - // Microsoft runtime hacking - if (add_permission == null) { - var assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData"); - add_permission = assembly_builder.GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic); - - FieldInfo fi = typeof (AssemblyBuilder).GetField ("m_assemblyData", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField); - builder_instance = fi.GetValue (Builder); - } - - var args = new PermissionSet [3]; - declarative_security.TryGetValue (SecurityAction.RequestMinimum, out args [0]); - declarative_security.TryGetValue (SecurityAction.RequestOptional, out args [1]); - declarative_security.TryGetValue (SecurityAction.RequestRefuse, out args [2]); - add_permission.Invoke (builder_instance, args); - } - catch { - Report.RuntimeMissingSupport (Location.Null, "assembly permission setting"); - } - } - } - - public override string[] ValidAttributeTargets { - get { - return attribute_targets; - } - } - - // Wrapper for AssemblyBuilder.AddModule - static MethodInfo adder_method; - static public MethodInfo AddModule_Method { - get { - if (adder_method == null) - adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic); - return adder_method; - } - } - public Module AddModule (string module) - { - MethodInfo m = AddModule_Method; - if (m == null) { - Report.RuntimeMissingSupport (Location.Null, "/addmodule"); - Environment.Exit (1); - } - - try { - return (Module) m.Invoke (Builder, new object [] { module }); - } catch (TargetInvocationException ex) { - throw ex.InnerException; - } - } - } } diff --git a/mcs/mcs/complete.cs b/mcs/mcs/complete.cs index 28a103b8c80..191c8cd5ae2 100644 --- a/mcs/mcs/complete.cs +++ b/mcs/mcs/complete.cs @@ -15,8 +15,6 @@ // using System; using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; using System.Text; using Mono.CSharp.Linq; using System.Linq; diff --git a/mcs/mcs/context.cs b/mcs/mcs/context.cs index 7f538b1b644..d8146c3a90a 100644 --- a/mcs/mcs/context.cs +++ b/mcs/mcs/context.cs @@ -35,6 +35,8 @@ namespace Mono.CSharp // A member definition of the context. For partial types definition use // CurrentTypeDefinition.PartialContainer otherwise the context is local // + // TODO: Obsolete it in this context, dynamic context cannot guarantee sensible value + // MemberCore CurrentMemberDefinition { get; } bool IsObsolete { get; } diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs index ed8e103cd77..92daf800c5b 100644 --- a/mcs/mcs/convert.cs +++ b/mcs/mcs/convert.cs @@ -13,7 +13,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs index 0f5a2886a2a..da55d66cf7c 100644 --- a/mcs/mcs/cs-tokenizer.cs +++ b/mcs/mcs/cs-tokenizer.cs @@ -17,7 +17,6 @@ using System.Text; using System.Collections.Generic; using System.IO; using System.Globalization; -using System.Reflection; using System.Diagnostics; namespace Mono.CSharp diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs index 2f423c479ff..88313f8b360 100644 --- a/mcs/mcs/decl.cs +++ b/mcs/mcs/decl.cs @@ -1063,6 +1063,10 @@ namespace Mono.CSharp { return true; var parentType = /* this as TypeSpec ?? */ DeclaringType; + + // It's null for module context + if (invocationType == null) + invocationType = InternalType.FakeInternalType; // // If only accessible to the current class or children @@ -1322,43 +1326,6 @@ namespace Mono.CSharp { return MemberName.GetSignatureForError (); } - public bool CheckAccessLevel (TypeSpec check_type) - { -// TODO: Use this instead -// return PartialContainer.Definition.IsAccessible (check_type); - - TypeSpec tb = PartialContainer.Definition; - check_type = check_type.GetDefinition (); - - var check_attr = check_type.Modifiers & Modifiers.AccessibilityMask; - - switch (check_attr){ - case Modifiers.PUBLIC: - return true; - - case Modifiers.INTERNAL: - return TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly); - - case Modifiers.PRIVATE: - TypeSpec declaring = check_type.DeclaringType; - return tb == declaring.GetDefinition () || TypeManager.IsNestedChildOf (tb, declaring); - - case Modifiers.PROTECTED: - // - // Only accessible to methods in current type or any subtypes - // - return TypeManager.IsNestedFamilyAccessible (tb, check_type.DeclaringType); - - case Modifiers.PROTECTED | Modifiers.INTERNAL: - if (TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly)) - return true; - - goto case Modifiers.PROTECTED; - } - - throw new NotImplementedException (check_attr.ToString ()); - } - public override Assembly Assembly { get { return Module.Assembly; } } diff --git a/mcs/mcs/dmcs.csproj b/mcs/mcs/dmcs.csproj index 154cad49494..e56157f79b3 100644 --- a/mcs/mcs/dmcs.csproj +++ b/mcs/mcs/dmcs.csproj @@ -1,154 +1,155 @@ - - - - Debug - AnyCPU - 10.0.20506 - 2.0 - {D4A01C5B-A1B5-48F5-BB5B-D2E1BD236E56} - Exe - Properties - dmcs - dmcs - v4.0 - 512 - x86 - - - true - full - false - .\ - TRACE;DEBUG;NET_4_0;MS_COMPATIBLE - prompt - 4 - true - - - pdbonly - true - TRACE;NET_2_0;MS_COMPATIBLE;GMCS_SOURCE - prompt - prompt - 4 - .\ - - - - - - - - - - CryptoConvert.cs - - - MonoSymbolFile.cs - - - MonoSymbolTable.cs - - - MonoSymbolWriter.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - outline.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Debug + AnyCPU + 10.0.20506 + 2.0 + {D4A01C5B-A1B5-48F5-BB5B-D2E1BD236E56} + Exe + Properties + dmcs + dmcs + v4.0 + 512 + x86 + + + true + full + false + .\ + TRACE;DEBUG;NET_4_0;MS_COMPATIBLE + prompt + 4 + true + + + pdbonly + true + TRACE;NET_2_0;MS_COMPATIBLE;GMCS_SOURCE + prompt + prompt + 4 + .\ + + + + + + + + + + CryptoConvert.cs + + + MonoSymbolFile.cs + + + MonoSymbolTable.cs + + + MonoSymbolWriter.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + outline.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --> \ No newline at end of file diff --git a/mcs/mcs/dmcs.exe.sources b/mcs/mcs/dmcs.exe.sources index 71a658ad1f3..4fc5e36120c 100644 --- a/mcs/mcs/dmcs.exe.sources +++ b/mcs/mcs/dmcs.exe.sources @@ -2,6 +2,7 @@ AssemblyInfo.cs anonymous.cs argument.cs assign.cs +assembly.cs attribute.cs cs-tokenizer.cs cfold.cs diff --git a/mcs/mcs/doc.cs b/mcs/mcs/doc.cs index 8d7afc74a6e..25c61c248ab 100644 --- a/mcs/mcs/doc.cs +++ b/mcs/mcs/doc.cs @@ -13,8 +13,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Reflection; -using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; diff --git a/mcs/mcs/dynamic.cs b/mcs/mcs/dynamic.cs index e6e042ea70d..81e552fd02c 100644 --- a/mcs/mcs/dynamic.cs +++ b/mcs/mcs/dynamic.cs @@ -50,11 +50,6 @@ namespace Mono.CSharp eclass = ExprClass.Type; } - public override bool CheckAccessLevel (IMemberContext ds) - { - return true; - } - protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec) { return this; diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 163af0e8a9f..179d0932ae2 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -211,7 +211,7 @@ namespace Mono.CSharp { return null; } - if (!te.CheckAccessLevel (ec)) { + if (!te.type.IsAccessible (ec.CurrentType)) { ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type); ErrorIsInaccesible (ec, te.Type.GetSignatureForError (), loc); } @@ -548,7 +548,7 @@ namespace Mono.CSharp { protected static MethodSpec ConstructorLookup (ResolveContext rc, TypeSpec type, ref Arguments args, Location loc) { - var ctors = MemberCache.FindMembers (type, ConstructorInfo.ConstructorName, true); + var ctors = MemberCache.FindMembers (type, Constructor.ConstructorName, true); if (ctors == null) { rc.Report.SymbolRelatedToPreviousError (type); if (type.IsStruct) { @@ -2498,15 +2498,6 @@ namespace Mono.CSharp { return ResolveAsTypeTerminal (ec, false); } - public virtual bool CheckAccessLevel (IMemberContext mc) - { - DeclSpace c = mc.CurrentMemberDefinition as DeclSpace; - if (c == null) - c = mc.CurrentMemberDefinition.Parent; - - return c.CheckAccessLevel (Type); - } - protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec); public override bool Equals (object obj) diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index eb477b57756..ea27893da5b 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -70,8 +70,7 @@ namespace Mono.CSharp { public override SLE.Expression MakeExpression (BuilderContext ctx) { - var method = oper.GetMetaInfo () as MethodInfo; - return SLE.Expression.Call (method, Arguments.MakeExpression (arguments, ctx)); + return SLE.Expression.Call ((MethodInfo) oper.GetMetaInfo (), Arguments.MakeExpression (arguments, ctx)); } } diff --git a/mcs/mcs/flowanalysis.cs b/mcs/mcs/flowanalysis.cs index 71d06a6668e..92fb60b30f4 100644 --- a/mcs/mcs/flowanalysis.cs +++ b/mcs/mcs/flowanalysis.cs @@ -12,8 +12,6 @@ using System; using System.Text; using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; using System.Diagnostics; namespace Mono.CSharp diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs index 3edf63e065b..f4a565c3861 100644 --- a/mcs/mcs/generic.cs +++ b/mcs/mcs/generic.cs @@ -1282,11 +1282,6 @@ namespace Mono.CSharp { { return this; } - - public override bool CheckAccessLevel (IMemberContext ds) - { - return true; - } } public class InflatedTypeSpec : TypeSpec @@ -1821,15 +1816,6 @@ namespace Mono.CSharp { return new ConstraintChecker(ec).CheckAll (open_type, args.Arguments, constraints, loc); } - - public override bool CheckAccessLevel (IMemberContext mc) - { - DeclSpace c = mc.CurrentMemberDefinition as DeclSpace; - if (c == null) - c = mc.CurrentMemberDefinition.Parent; - - return c.CheckAccessLevel (open_type); - } public bool HasDynamicArguments () { diff --git a/mcs/mcs/gmcs.exe.sources b/mcs/mcs/gmcs.exe.sources index 03738c50321..a60aa9c6b45 100644 --- a/mcs/mcs/gmcs.exe.sources +++ b/mcs/mcs/gmcs.exe.sources @@ -2,6 +2,7 @@ AssemblyInfo.cs anonymous.cs argument.cs assign.cs +assembly.cs attribute.cs cs-tokenizer.cs cfold.cs diff --git a/mcs/mcs/iterators.cs b/mcs/mcs/iterators.cs index 0cfccd0759e..97ad5e42965 100644 --- a/mcs/mcs/iterators.cs +++ b/mcs/mcs/iterators.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { diff --git a/mcs/mcs/lambda.cs b/mcs/mcs/lambda.cs index 42a096dab12..3bebbbfa2e7 100644 --- a/mcs/mcs/lambda.cs +++ b/mcs/mcs/lambda.cs @@ -10,7 +10,6 @@ // using System; -using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { diff --git a/mcs/mcs/linq.cs b/mcs/mcs/linq.cs index 02042beaef0..7b3495eef36 100644 --- a/mcs/mcs/linq.cs +++ b/mcs/mcs/linq.cs @@ -9,7 +9,6 @@ // using System; -using System.Reflection; using System.Collections.Generic; namespace Mono.CSharp.Linq diff --git a/mcs/mcs/literal.cs b/mcs/mcs/literal.cs index 0fd978219bc..705359a89f4 100644 --- a/mcs/mcs/literal.cs +++ b/mcs/mcs/literal.cs @@ -20,7 +20,6 @@ // using System; -using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { diff --git a/mcs/mcs/membercache.cs b/mcs/mcs/membercache.cs index 9fdf4506693..bfa57040a4b 100644 --- a/mcs/mcs/membercache.cs +++ b/mcs/mcs/membercache.cs @@ -14,7 +14,6 @@ using System; using System.Text; using System.Collections.Generic; -using System.Reflection; using System.Linq; namespace Mono.CSharp { @@ -801,9 +800,9 @@ namespace Mono.CSharp { if (ms.Kind == MemberKind.Constructor) { if (ms.IsStatic) - return ConstructorInfo.TypeConstructorName; + return Constructor.TypeConstructorName; - return ConstructorInfo.ConstructorName; + return Constructor.ConstructorName; } return ms.Name; @@ -815,7 +814,7 @@ namespace Mono.CSharp { return IndexerNameAlias; if (mc is Constructor) - return ConstructorInfo.ConstructorName; + return Constructor.ConstructorName; return mc.MemberName.Name; } diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs index 3e97804fe22..654677138bc 100644 --- a/mcs/mcs/method.cs +++ b/mcs/mcs/method.cs @@ -1336,6 +1336,9 @@ namespace Mono.CSharp { static readonly string[] attribute_targets = new string [] { "method" }; + public static readonly string ConstructorName = ".ctor"; + public static readonly string TypeConstructorName = ".cctor"; + // // The spec claims that static is not permitted, but // my very own code has static constructors. diff --git a/mcs/mcs/nullable.cs b/mcs/mcs/nullable.cs index cd35b319e59..646bdf74941 100644 --- a/mcs/mcs/nullable.cs +++ b/mcs/mcs/nullable.cs @@ -12,7 +12,6 @@ // using System; -using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp.Nullable diff --git a/mcs/mcs/report.cs b/mcs/mcs/report.cs index b63b74d539b..cb849513174 100644 --- a/mcs/mcs/report.cs +++ b/mcs/mcs/report.cs @@ -12,7 +12,6 @@ using System.IO; using System.Text; using System.Collections.Generic; using System.Diagnostics; -using System.Reflection; namespace Mono.CSharp { @@ -907,7 +906,7 @@ namespace Mono.CSharp { for (int i = 0; i < t.FrameCount; i++) { StackFrame f = t.GetFrame (i); - MethodBase mb = f.GetMethod (); + var mb = f.GetMethod (); if (!foundUserCode && mb.ReflectedType == typeof (Report)) continue; @@ -922,7 +921,7 @@ namespace Mono.CSharp { sb.AppendFormat ("{0}.{1} (", mb.ReflectedType.Name, mb.Name); bool first = true; - foreach (ParameterInfo pi in mb.GetParameters ()) { + foreach (var pi in mb.GetParameters ()) { if (!first) sb.Append (", "); first = false; diff --git a/mcs/mcs/smcs.exe.sources b/mcs/mcs/smcs.exe.sources index 208d2eee290..92e3d3bb467 100644 --- a/mcs/mcs/smcs.exe.sources +++ b/mcs/mcs/smcs.exe.sources @@ -2,6 +2,7 @@ AssemblyInfo.cs anonymous.cs argument.cs assign.cs +assembly.cs attribute.cs driver.cs cs-tokenizer.cs diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index feabce3feb8..ff2bb47c020 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -12,7 +12,6 @@ using System; using System.Text; -using System.Reflection; using System.Reflection.Emit; using System.Diagnostics; using System.Collections.Generic; diff --git a/mcs/mcs/support.cs b/mcs/mcs/support.cs index e9f578a11d9..d4b933f38e7 100644 --- a/mcs/mcs/support.cs +++ b/mcs/mcs/support.cs @@ -13,8 +13,6 @@ using System; using System.IO; using System.Text; -using System.Reflection; -using System.Reflection.Emit; using System.Globalization; using System.Collections.Generic; diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs index ba528c836c3..991319087dc 100644 --- a/mcs/mcs/typemanager.cs +++ b/mcs/mcs/typemanager.cs @@ -16,7 +16,6 @@ using System.IO; using System.Globalization; using System.Collections.Generic; using System.Reflection; -using System.Reflection.Emit; using System.Text; using System.Runtime.CompilerServices; using System.Diagnostics; diff --git a/mono-core.spec.in b/mono-core.spec.in index ce41a42c8ae..6bebeed1504 100644 --- a/mono-core.spec.in +++ b/mono-core.spec.in @@ -985,6 +985,7 @@ Mono development tools. %_bindir/monolinker %_bindir/monop %_bindir/monop2 +%_bindir/mprof-report %_bindir/pdb2mdb %_bindir/pedump %_bindir/permview @@ -1002,6 +1003,7 @@ Mono development tools. %_libdir/libmono-profiler-aot.* %_libdir/libmono-profiler-cov.* %_libdir/libmono-profiler-iomap.* +%_libdir/libmono-profiler-log.* %_libdir/libmono-profiler-logging.* %_libdir/pkgconfig/cecil.pc %_libdir/pkgconfig/dotnet.pc @@ -1028,6 +1030,7 @@ Mono development tools. %_mandir/man1/monodis.1%ext_man %_mandir/man1/monolinker.1%ext_man %_mandir/man1/monop.1%ext_man +%_mandir/man1/mprof-report.1%ext_man %_mandir/man1/pdb2mdb.1%ext_man %_mandir/man1/permview.1%ext_man %_mandir/man1/prj2make.1%ext_man diff --git a/mono/CMakeLists.txt b/mono/CMakeLists.txt deleted file mode 100644 index ed828cea7cd..00000000000 --- a/mono/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(SUBDIRS utils io-layer cil metadata - arch interpreter mini dis monograph tests benchmark profiler) - -foreach(subdir ${SUBDIRS}) - add_subdirectory(${subdir}) -endforeach() \ No newline at end of file diff --git a/mono/dis/CMakeLists.txt b/mono/dis/CMakeLists.txt deleted file mode 100644 index f482df3df43..00000000000 --- a/mono/dis/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -if(HOST_WIN32) -###export HOST_CC -endif() - -set(libmonodis_a_SOURCES - get.c - get.h - dis-cil.c - dis-cil.h - util.c - util.h) - -set(monodis_SOURCES - dump.c - dump.h - main.c - meta.h - declsec.c - declsec.h) - -set(monodis_LDADD - libmonodis.a - ${runtime_lib} - ${GLIB_LIBS}) - -include_directories(${top_srcdir}) -include_directories(${GLIB2_INCLUDE_DIRS}) -set(CMAKE_C_FLAGS "${CFLAGS} ${CPPFLAGS}") - -# FIXME: cmake doesn't seem to link the libs together into libmono-static.a -link_directories(../../libgc/.libs) - -add_executable(monodis ${libmonodis_a_SOURCES} ${monodis_SOURCES}) -target_link_libraries(monodis mono-static ${GLIB_LIBS}) - -###bin_PROGRAMS monodis - -###noinst_LIBRARIES libmonodis.a - -###man_MANS monodis.1 - -###EXTRA_DIST ${man_MANS} diff --git a/mono/io-layer/CMakeLists.txt b/mono/io-layer/CMakeLists.txt deleted file mode 100644 index 2998be7891d..00000000000 --- a/mono/io-layer/CMakeLists.txt +++ /dev/null @@ -1,142 +0,0 @@ - -# Last synched with Makefile.am at r134597 - -set(OTHER_H - access.h - atomic.h - collection.h - context.h - critical-sections.h - error.h - events.h - handles.h - io.h - io-layer.h - io-portability.h - macros.h - messages.h - mono-mutex.h - mutexes.h - processes.h - security.h - semaphores.h - sockets.h - status.h - system.h - threads.h - timefuncs.h - types.h - uglify.h - versioninfo.h - wait.h - wapi.h) - -set(OTHER_SRC - access.h - atomic.c - atomic.h - collection.c - collection.h - context.c - context.h - critical-sections.c - critical-sections.h - critical-section-private.h - error.c - error.h - events.c - events.h - event-private.h - handles.c - handles.h - handles-private.h - io.c - io.h - io-portability.c - io-portability.h - io-private.h - io-layer.h - locking.c - macros.h - messages.c - messages.h - misc.c - misc-private.h - mutexes.c - mutexes.h - mutex-private.h - mono-mutex.c - mono-mutex.h - mono-spinlock.h - posix.c - processes.c - processes.h - process-private.h - security.c - security.h - semaphores.c - semaphores.h - semaphore-private.h - shared.c - shared.h - sockets.c - sockets.h - socket-private.h - socket-wrappers.h - status.h - system.c - system.h - threads.h - thread-private.h - timefuncs.c - timefuncs.h - timefuncs-private.h - types.h - uglify.h - versioninfo.c - versioninfo.h - wait.c - wait.h - wapi_glob.h - wapi_glob.c - wapi.h - wapi-private.h - wthreads.c) - -set(WINDOWS_H - io-layer.h) - -set(WINDOWS_SRC - io-layer.h - io-layer-dummy.c) - -set(HPPA_SRC - hppa_atomic.S) - -if(HOST_WIN32) -###if HOST_WIN32 -###libwapi_la_SOURCES = $(WINDOWS_SRC) -###libwapiinclude_HEADERS = $(WINDOWS_H) -else() -###if HPPA -###libwapi_la_SOURCES = $(OTHER_SRC) $(HPPA_SRC) -#### to enable pick up of config.h -###libwapi_la_CCASFLAGS = -I$(top_builddir) -###else -set(libwapi_la_SOURCES ${OTHER_SRC}) -###endif -###libwapiinclude_HEADERS = $(OTHER_H) -###endif -endif() - -###EXTRA_DIST = -### $(WINDOWS_SRC) -### $(HPPA_SRC) \ -### $(OTHER_SRC) - -set(top_srcdir ../../) -include_directories(${top_srcdir} ${top_srcdir}/mono ${GLIB2_INCLUDE_DIRS}) -add_definitions(${CFLAGS} ${LIBGC_CFLAGS} ${CPPFLAGS}) - -add_library(wapi-static STATIC ${libwapi_la_SOURCES}) -add_library(wapi SHARED ${libwapi_la_SOURCES}) diff --git a/mono/metadata/CMakeLists.txt b/mono/metadata/CMakeLists.txt deleted file mode 100644 index db58f9dd082..00000000000 --- a/mono/metadata/CMakeLists.txt +++ /dev/null @@ -1,234 +0,0 @@ -if(HOST_WIN32) -###win32_sources = \ -### console-win32.c - -###platform_sources = $(win32_sources) - -#### Use -m here. This will use / as directory separator (C:/WINNT). -#### The files that use MONO_ASSEMBLIES and/or MONO_CFG_DIR replace the -#### / by \ if running under WIN32. -###if CROSS_COMPILING -###assembliesdir = ${libdir} -###confdir = ${sysconfdir} -###else -###assembliesdir = `cygpath -m "${libdir}"` -###confdir = `cygpath -m "${sysconfdir}"` -###endif -###export HOST_CC -#### The mingw math.h has "extern inline" functions that dont appear in libs, so -#### optimisation is required to actually inline them -###AM_CFLAGS = -O - -else() - -# FIXME: -set(assembliesdir ${CMAKE_INSTALL_PREFIX}/lib) -set(sysconfdir ${CMAKE_INSTALL_PREFIX}/etc) -set(confdir ${sysconfdir}) -###assembliesdir = $(exec_prefix)/lib -###confdir = $(sysconfdir) - -set(unix_sources - console-unix.c) - -set(platform_sources ${unix_sources}) - -endif(HOST_WIN32) - -###bin_PROGRAMS = pedump - -# -#### libtool is not capable of creating static/shared versions of the same -#### convenience lib, so we have to do it ourselves -# -###noinst_LTLIBRARIES = libmonoruntime.la libmonoruntime-static.la - -set(top_srcdir ../../) -INCLUDE_DIRECTORIES(${top_srcdir} ${top_srcdir}/mono ${GLIB2_INCLUDE_DIRS}) -ADD_DEFINITIONS("-DMONO_BINDIR=\"${CMAKE_BINARY_DIR}\"") -ADD_DEFINITIONS("-DMONO_ASSEMBLIES=\"${assembliesdir}\"") -ADD_DEFINITIONS("-DMONO_CFG_DIR=\"${confdir}\"") -ADD_DEFINITIONS(${CFLAGS} ${LIBGC_CFLAGS} ${CPPFLAGS}) - -# -#### Make sure any prefix changes are updated in the binaries too. -# -#### assembly.c uses MONO_ASSEMBLIES -#### mono-config.c uses MONO_CFG_DIR -# -#### This won't result in many more false positives than AC_DEFINEing them -#### in configure.in. -# -###assembly.lo mono-config.lo: Makefile - -###CLEANFILES = mono-bundle.stamp - -###libmonoruntime_static_la_LIBADD = $(bundle_obj) $(libmonoruntime_la_LIBADD) - -set(null_sources - console-null.c) - -set(libmonoruntime_la_SOURCES - ${platform_sources} - appdomain.c - assembly.c - attach.h - attach.c - boehm-gc.c - char-conversions.h - cil-coff.h - class.c - class-internals.h - cominterop.c - cominterop.h - console-io.h - coree.c - coree.h - culture-info.h - culture-info-tables.h - debug-helpers.c - debug-mono-symfile.h - debug-mono-symfile.c - decimal.c - decimal.h - domain.c - domain-internals.h - environment.c - environment.h - exception.c - exception.h - file-io.c - file-io.h - filewatcher.c - filewatcher.h - gc.c - gc-internal.h - generic-sharing.c - icall.c - icall-def.h - image.c - loader.c - locales.c - locales.h - lock-tracer.c - lock-tracer.h - marshal.c - marshal.h - mempool.c - mempool-internals.h - metadata.c - metadata-verify.c - metadata-internals.h - method-builder.h - method-builder.c - mono-config.c - mono-debug.h - mono-debug.c - mono-debug-debugger.h - mono-debug-debugger.c - mono-endian.c - mono-endian.h - mono-mlist.c - mono-mlist.h - mono-perfcounters.c - mono-perfcounters.h - mono-perfcounters-def.h - monitor.c - monitor.h - normalization-tables.h - null-gc.c - number-formatter.h - object.c - object-internals.h - opcodes.c - socket-io.c - socket-io.h - process.c - process.h - profiler.c - profiler-private.h - rand.h - rand.c - reflection.c - security.c - security.h - security-core-clr.c - security-core-clr.h - security-manager.c - security-manager.h - sgen-gc.c - sgen-gc.h - sgen-archdep.h - sgen-scan-object.h - string-icalls.c - string-icalls.h - sysmath.h - sysmath.c - tabledefs.h - threads.c - threads-types.h - threadpool.c - threadpool.h - threadpool-internals.h - verify.c - verify-internals.h - wrapper-types.h) - -set(libmonoruntime_static_la_SOURCES ${libmonoruntime_la_SOURCES}) - -###libmonoruntimeincludedir = $(includedir)/mono-$(API_VER)/mono/metadata - -###libmonoruntimeinclude_HEADERS = \ -### assembly.h \ -### attrdefs.h \ -### appdomain.h \ -### blob.h \ -### class.h \ -### debug-helpers.h \ -### debug-mono-symfile.h \ -### threads.h \ -### environment.h \ -### exception.h \ -### image.h \ -### loader.h \ -### mempool.h \ -### metadata.h \ -### mono-config.h \ -### mono-debug.h \ -### mono-gc.h \ -### object.h \ -### opcodes.h \ -### profiler.h \ -### reflection.h \ -### row-indexes.h \ -### tokentype.h \ -### verify.h - -#ADD_LIBRARY(libmonoruntime SHARED ${libmonoruntime_la_SOURCES}) - -###if DTRACE_G_REQUIRED - -###PEDUMP_DTRACE_OBJECT = pedump-dtrace.$(OBJEXT) - -###pedump-dtrace.$(OBJEXT): $(top_srcdir)/data/mono.d libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la -### DTRACE="$(DTRACE)" DTRACEFLAGS="$(DTRACEFLAGS)" AR="$(AR)" $(SHELL) $(top_srcdir)/data/dtrace-prelink.sh \ -### --pic pedump-dtrace.$(OBJEXT) $(top_srcdir)/data/mono.d libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la - -###else -###PEDUMP_DTRACE_OBJECT = -###endif - -add_library(monoruntime-static STATIC ${libmonoruntime_static_la_SOURCES}) -#add_library(monoruntime SHARED ${libmonoruntime_static_la_SOURCES}) -#target_link_libraries(monoruntime wapi monoutils monogc ${GLIB2_LIBRARIES} ${LIBS}) - -# FIXME: -link_directories(../../libgc/.libs) -add_executable(pedump pedump.c) -target_link_libraries(pedump monoruntime-static wapi monoutils monogc-static ${GLIB2_LIBRARIES} ${LIBS}) - -###pedump_LDADD = libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la \ -### $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(PEDUMP_DTRACE_OBJECT) - -###EXTRA_DIST = make-bundle.pl sample-bundle $(win32_sources) $(unix_sources) $(null_sources) - diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 11051ad8731..e0c7519c479 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -7207,12 +7207,16 @@ mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass) gboolean mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) { + /*FIXME this will cause a lot of irrelevant stuff to be loaded.*/ if (!klass->inited) mono_class_init (klass); if (!oklass->inited) mono_class_init (oklass); + if (klass->exception_type || oklass->exception_type) + return FALSE; + if ((klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR)) return klass == oklass; diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index bd0f8356a43..732167b6097 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -611,9 +611,11 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con continue; method = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass); - other_sig = mono_method_signature (method); - if (method && other_sig && (sig->call_convention != MONO_CALL_VARARG) && mono_metadata_signature_equal (sig, other_sig)) - return method; + if (method) { + other_sig = mono_method_signature (method); + if (other_sig && (sig->call_convention != MONO_CALL_VARARG) && mono_metadata_signature_equal (sig, other_sig)) + return method; + } } } @@ -629,6 +631,10 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con MonoMethod *m = klass->methods [i]; MonoMethodSignature *msig; + /* We must cope with failing to load some of the types. */ + if (!m) + continue; + if (!((fqname && !strcmp (m->name, fqname)) || (qname && !strcmp (m->name, qname)) || (name && !strcmp (m->name, name)))) @@ -681,7 +687,16 @@ find_method (MonoClass *in_class, MonoClass *ic, const char* name, MonoMethodSig if (name [0] == '.' && (!strcmp (name, ".ctor") || !strcmp (name, ".cctor"))) break; - g_assert (from_class->interface_offsets_count == in_class->interface_offsets_count); + /* + * This happens when we fail to lazily load the interfaces of one of the types. + * On such case we can't just bail out since user code depends on us trying harder. + */ + if (from_class->interface_offsets_count != in_class->interface_offsets_count) { + in_class = in_class->parent; + from_class = from_class->parent; + continue; + } + for (i = 0; i < in_class->interface_offsets_count; i++) { MonoClass *in_ic = in_class->interfaces_packed [i]; MonoClass *from_ic = from_class->interfaces_packed [i]; diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index ec3be7090db..956f232088b 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -1413,7 +1413,11 @@ conv_to_icall (MonoMarshalConv conv) case MONO_MARSHAL_CONV_LPWSTR_STR: return mono_string_from_utf16; case MONO_MARSHAL_CONV_LPSTR_STR: +#ifdef TARGET_WIN32 + return mono_string_from_utf16; +#else return mono_string_new_wrapper; +#endif case MONO_MARSHAL_CONV_STR_LPTSTR: #ifdef TARGET_WIN32 return mono_marshal_string_to_utf16; diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c index 97712fa73c1..a3f61a813a6 100644 --- a/mono/metadata/metadata-verify.c +++ b/mono/metadata/metadata-verify.c @@ -2883,8 +2883,8 @@ verify_cattr_table (VerifyContext *ctx) if (!is_valid_coded_index (ctx, HAS_CATTR_DESC, data [MONO_CUSTOM_ATTR_PARENT])) ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT])); - if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE])) - ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT])); + if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]) || !get_coded_index_token (CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE])) + ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Type field 0x%08x", i, data [MONO_CUSTOM_ATTR_TYPE])); if (data [MONO_CUSTOM_ATTR_VALUE] && !is_valid_blob_object (ctx, data [MONO_CUSTOM_ATTR_VALUE], 0)) ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d invalid value blob 0x%x", i, data [MONO_CUSTOM_ATTR_VALUE])); diff --git a/mono/metadata/mono-gc.h b/mono/metadata/mono-gc.h index a09f9a12ed7..f2ff92b53b8 100644 --- a/mono/metadata/mono-gc.h +++ b/mono/metadata/mono-gc.h @@ -9,7 +9,7 @@ MONO_BEGIN_DECLS -typedef int (*MonoGCReferences) (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, void *data); +typedef int (*MonoGCReferences) (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, uintptr_t *offsets, void *data); void mono_gc_collect (int generation); int mono_gc_max_generation (void); diff --git a/mono/metadata/process.c b/mono/metadata/process.c index 5dc231eb8bc..f970878cf5a 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -65,7 +65,7 @@ void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *thi g_message ("%s: Closing process %p, handle %p", __func__, this, process); #endif -#if TARGET_WIN32 +#if defined(TARGET_WIN32) || defined(HOST_WIN32) CloseHandle (process); #else CloseProcess (process); diff --git a/mono/metadata/profiler-private.h b/mono/metadata/profiler-private.h index 809e483e8c9..18ec96b7aea 100644 --- a/mono/metadata/profiler-private.h +++ b/mono/metadata/profiler-private.h @@ -69,6 +69,7 @@ void mono_profiler_gc_event (MonoGCEvent e, int generation) MONO_INTERNAL; void mono_profiler_gc_heap_resize (gint64 new_size) MONO_INTERNAL; void mono_profiler_gc_moves (void **objects, int num) MONO_INTERNAL; void mono_profiler_gc_handle (int op, int type, uintptr_t handle, MonoObject *obj) MONO_INTERNAL; +void mono_profiler_gc_roots (int num, void **objects, int *root_types, uintptr_t *extra_info) MONO_INTERNAL; void mono_profiler_code_chunk_new (gpointer chunk, int size) MONO_INTERNAL; void mono_profiler_code_chunk_destroy (gpointer chunk) MONO_INTERNAL; diff --git a/mono/metadata/profiler.c b/mono/metadata/profiler.c index 52d68739fb2..0e4a0ce4bdc 100644 --- a/mono/metadata/profiler.c +++ b/mono/metadata/profiler.c @@ -91,6 +91,7 @@ struct _ProfilerDesc { MonoProfileGCResizeFunc gc_heap_resize; MonoProfileGCMoveFunc gc_moves; MonoProfileGCHandleFunc gc_handle; + MonoProfileGCRootFunc gc_roots; MonoProfileFunc runtime_initialized_event; @@ -770,6 +771,16 @@ mono_profiler_gc_handle (int op, int type, uintptr_t handle, MonoObject *obj) } } +void +mono_profiler_gc_roots (int num, void **objects, int *root_types, uintptr_t *extra_info) +{ + ProfilerDesc *prof; + for (prof = prof_list; prof; prof = prof->next) { + if ((prof->events & MONO_PROFILE_GC_ROOTS) && prof->gc_roots) + prof->gc_roots (prof->profiler, num, objects, root_types, extra_info); + } +} + void mono_profiler_install_gc (MonoProfileGCFunc callback, MonoProfileGCResizeFunc heap_resize_callback) { @@ -805,19 +816,26 @@ mono_profiler_install_gc_moves (MonoProfileGCMoveFunc callback) /** * mono_profiler_install_gc_roots: * @handle_callback: callback function + * @roots_callback: callback function * * Install the @handle_callback function that the GC will call when GC * handles are created or destroyed. * The callback receives an operation, which is either #MONO_PROFILER_GC_HANDLE_CREATED * or #MONO_PROFILER_GC_HANDLE_DESTROYED, the handle type, the handle value and the * object pointer, if present. + * Install the @roots_callback function that the GC will call when tracing + * the roots for a collection. + * The callback receives the number of elements and three arrays: an array + * of objects, an array of root types and flags and an array of extra info. + * The size of each array is given by the first argument. */ void -mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback) +mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback, MonoProfileGCRootFunc roots_callback) { if (!prof_list) return; prof_list->gc_handle = handle_callback; + prof_list->gc_roots = roots_callback; } void diff --git a/mono/metadata/profiler.h b/mono/metadata/profiler.h index 79f5f6f01af..09299a7cfd7 100644 --- a/mono/metadata/profiler.h +++ b/mono/metadata/profiler.h @@ -89,6 +89,19 @@ typedef enum { MONO_PROFILER_GC_HANDLE_DESTROYED } MonoProfileGCHandleEvent; +typedef enum { + MONO_PROFILE_GC_ROOT_PINNING = 1 << 8, + MONO_PROFILE_GC_ROOT_WEAKREF = 2 << 8, + MONO_PROFILE_GC_ROOT_INTERIOR = 4 << 8, + /* the above are flags, the type is in the low 2 bytes */ + MONO_PROFILE_GC_ROOT_STACK = 0, + MONO_PROFILE_GC_ROOT_FINALIZER = 1, + MONO_PROFILE_GC_ROOT_HANDLE = 2, + MONO_PROFILE_GC_ROOT_OTHER = 3, + MONO_PROFILE_GC_ROOT_MISC = 4, /* could be stack, handle, etc. */ + MONO_PROFILE_GC_ROOT_TYPEMASK = 0xff +} MonoProfileGCRootType; + /* * Functions that the runtime will call on the profiler. */ @@ -123,6 +136,7 @@ typedef void (*MonoProfileGCFunc) (MonoProfiler *prof, MonoGCEvent event typedef void (*MonoProfileGCMoveFunc) (MonoProfiler *prof, void **objects, int num); typedef void (*MonoProfileGCResizeFunc) (MonoProfiler *prof, int64_t new_size); typedef void (*MonoProfileGCHandleFunc) (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj); +typedef void (*MonoProfileGCRootFunc) (MonoProfiler *prof, int num_roots, void **objects, int *root_types, uintptr_t *extra_info); typedef void (*MonoProfileIomapFunc) (MonoProfiler *prof, const char *report, const char *pathname, const char *new_pathname); @@ -168,7 +182,7 @@ void mono_profiler_install_coverage_filter (MonoProfileCoverageFilterFunc callba void mono_profiler_coverage_get (MonoProfiler *prof, MonoMethod *method, MonoProfileCoverageFunc func); void mono_profiler_install_gc (MonoProfileGCFunc callback, MonoProfileGCResizeFunc heap_resize_callback); void mono_profiler_install_gc_moves (MonoProfileGCMoveFunc callback); -void mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback); +void mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback, MonoProfileGCRootFunc roots_callback); void mono_profiler_install_runtime_initialized (MonoProfileFunc runtime_initialized_callback); void mono_profiler_install_code_chunk_new (MonoProfilerCodeChunkNew callback); diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index f75772f1ad9..56c44cf3f78 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -2870,6 +2870,8 @@ mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderI MonoMethod *method, *inflated; int count, i; + init_type_builder_generics ((MonoObject*)m->inst); + method = inflate_method (m->inst, (MonoObject*)m->mb); klass = method->klass; diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c index 9f1fdbbd51a..47542393e51 100644 --- a/mono/metadata/sgen-gc.c +++ b/mono/metadata/sgen-gc.c @@ -607,6 +607,33 @@ static int roots_hash_size [ROOT_TYPE_NUM] = { 0, 0, 0 }; static mword roots_size = 0; /* amount of memory in the root set */ static int num_roots_entries [ROOT_TYPE_NUM] = { 0, 0, 0 }; +#define GC_ROOT_NUM 32 +typedef struct { + int count; + void *objects [GC_ROOT_NUM]; + int root_types [GC_ROOT_NUM]; + uintptr_t extra_info [GC_ROOT_NUM]; +} GCRootReport; + +static void +notify_gc_roots (GCRootReport *report) +{ + if (!report->count) + return; + mono_profiler_gc_roots (report->count, report->objects, report->root_types, report->extra_info); + report->count = 0; +} + +static void +add_profile_gc_root (GCRootReport *report, void *object, int rtype, uintptr_t extra_info) +{ + if (report->count == GC_ROOT_NUM) + notify_gc_roots (report); + report->objects [report->count] = object; + report->root_types [report->count] = rtype; + report->extra_info [report->count++] = ((MonoVTable*)LOAD_VTABLE (object))->klass; +} + /* * The current allocation cursors * We allocate objects in the nursery. @@ -785,6 +812,8 @@ static void scan_thread_data (void *start_nursery, void *end_nursery, gboolean p static void scan_from_remsets (void *start_nursery, void *end_nursery, GrayQueue *queue); static void scan_from_registered_roots (CopyOrMarkObjectFunc copy_func, char *addr_start, char *addr_end, int root_type, GrayQueue *queue); static void scan_finalizer_entries (CopyOrMarkObjectFunc copy_func, FinalizeEntry *list, GrayQueue *queue); +static void report_finalizer_roots (void); +static void report_registered_roots (void); static void find_pinning_ref_from_thread (char *obj, size_t size); static void update_current_thread_stack (void *start); static void finalize_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int generation, GrayQueue *queue); @@ -1793,6 +1822,13 @@ pin_objects_from_addresses (GCMemSection *section, void **start, void **end, voi start++; } //printf ("effective pinned: %d (at the end: %d)\n", count, (char*)end_nursery - (char*)last); + if (mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS) { + GCRootReport report; + report.count = 0; + for (idx = 0; idx < count; ++idx) + add_profile_gc_root (&report, definitely_pinned [idx], MONO_PROFILE_GC_ROOT_PINNING, 0); + notify_gc_roots (&report); + } return count; } @@ -2207,6 +2243,106 @@ mono_gc_get_nursery (int *shift_bits, size_t *size) return nursery_start; } +static void +report_finalizer_roots_list (FinalizeEntry *list) +{ + GCRootReport report; + FinalizeEntry *fin; + + report.count = 0; + for (fin = list; fin; fin = fin->next) { + if (!fin->object) + continue; + add_profile_gc_root (&report, fin->object, MONO_PROFILE_GC_ROOT_FINALIZER, 0); + } + notify_gc_roots (&report); +} + +static void +report_finalizer_roots (void) +{ + report_finalizer_roots_list (fin_ready_list); + report_finalizer_roots_list (critical_fin_list); +} + +static GCRootReport *root_report; + +static void +single_arg_report_root (void **obj) +{ + if (*obj) + add_profile_gc_root (root_report, *obj, MONO_PROFILE_GC_ROOT_OTHER, 0); +} + +static void +precisely_report_roots_from (GCRootReport *report, void** start_root, void** end_root, mword desc) +{ + switch (desc & ROOT_DESC_TYPE_MASK) { + case ROOT_DESC_BITMAP: + desc >>= ROOT_DESC_TYPE_SHIFT; + while (desc) { + if ((desc & 1) && *start_root) { + add_profile_gc_root (report, *start_root, MONO_PROFILE_GC_ROOT_OTHER, 0); + } + desc >>= 1; + start_root++; + } + return; + case ROOT_DESC_COMPLEX: { + gsize *bitmap_data = complex_descriptors + (desc >> ROOT_DESC_TYPE_SHIFT); + int bwords = (*bitmap_data) - 1; + void **start_run = start_root; + bitmap_data++; + while (bwords-- > 0) { + gsize bmap = *bitmap_data++; + void **objptr = start_run; + while (bmap) { + if ((bmap & 1) && *objptr) { + add_profile_gc_root (report, *objptr, MONO_PROFILE_GC_ROOT_OTHER, 0); + } + bmap >>= 1; + ++objptr; + } + start_run += GC_BITS_PER_WORD; + } + break; + } + case ROOT_DESC_USER: { + MonoGCRootMarkFunc marker = user_descriptors [desc >> ROOT_DESC_TYPE_SHIFT]; + root_report = report; + marker (start_root, single_arg_report_root); + break; + } + case ROOT_DESC_RUN_LEN: + g_assert_not_reached (); + default: + g_assert_not_reached (); + } +} + +static void +report_registered_roots_by_type (int root_type) +{ + GCRootReport report; + int i; + RootRecord *root; + report.count = 0; + for (i = 0; i < roots_hash_size [root_type]; ++i) { + for (root = roots_hash [root_type][i]; root; root = root->next) { + DEBUG (6, fprintf (gc_debug_file, "Precise root scan %p-%p (desc: %p)\n", root->start_root, root->end_root, (void*)root->root_desc)); + precisely_report_roots_from (&report, (void**)root->start_root, (void**)root->end_root, root->root_desc); + } + } + notify_gc_roots (&report); +} + +static void +report_registered_roots (void) +{ + report_registered_roots_by_type (ROOT_TYPE_NORMAL); + report_registered_roots_by_type (ROOT_TYPE_WBARRIER); +} + static void scan_finalizer_entries (CopyOrMarkObjectFunc copy_func, FinalizeEntry *list, GrayQueue *queue) { @@ -2774,6 +2910,10 @@ collect_nursery (size_t requested_size) drain_gray_stack (&gray_queue); + if (mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS) + report_registered_roots (); + if (mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS) + report_finalizer_roots (); TV_GETTIME (atv); time_minor_scan_pinned += TV_ELAPSED_MS (btv, atv); /* registered roots, this includes static fields */ @@ -2965,6 +3105,8 @@ major_do_collection (const char *reason) workers_start_all_workers (1); + if (mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS) + report_registered_roots (); TV_GETTIME (atv); time_major_scan_pinned += TV_ELAPSED_MS (btv, atv); @@ -2984,6 +3126,8 @@ major_do_collection (const char *reason) TV_GETTIME (btv); time_major_scan_alloc_pinned += TV_ELAPSED_MS (atv, btv); + if (mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS) + report_finalizer_roots (); /* scan the list of objects ready for finalization */ scan_finalizer_entries (major_collector.copy_or_mark_object, fin_ready_list, WORKERS_DISTRIBUTE_GRAY_QUEUE); scan_finalizer_entries (major_collector.copy_or_mark_object, critical_fin_list, WORKERS_DISTRIBUTE_GRAY_QUEUE); @@ -6329,16 +6473,18 @@ typedef struct { int count; int called; MonoObject *refs [REFS_SIZE]; + uintptr_t offsets [REFS_SIZE]; } HeapWalkInfo; #undef HANDLE_PTR #define HANDLE_PTR(ptr,obj) do { \ if (*(ptr)) { \ if (hwi->count == REFS_SIZE) { \ - hwi->callback ((MonoObject*)start, mono_object_class (start), hwi->called? 0: size, hwi->count, hwi->refs, hwi->data); \ + hwi->callback ((MonoObject*)start, mono_object_class (start), hwi->called? 0: size, hwi->count, hwi->refs, hwi->offsets, hwi->data); \ hwi->count = 0; \ hwi->called = 1; \ } \ + hwi->offsets [hwi->count] = (char*)(ptr)-(char*)start; \ hwi->refs [hwi->count++] = *(ptr); \ } \ } while (0) @@ -6357,7 +6503,7 @@ walk_references (char *start, size_t size, void *data) hwi->count = 0; collect_references (hwi, start, size); if (hwi->count || !hwi->called) - hwi->callback ((MonoObject*)start, mono_object_class (start), hwi->called? 0: size, hwi->count, hwi->refs, hwi->data); + hwi->callback ((MonoObject*)start, mono_object_class (start), hwi->called? 0: size, hwi->count, hwi->refs, hwi->offsets, hwi->data); } /** @@ -6369,6 +6515,8 @@ walk_references (char *start, size_t size, void *data) * This function can be used to iterate over all the live objects in the heap: * for each object, @callback is invoked, providing info about the object's * location in memory, its class, its size and the objects it references. + * For each referenced object it's offset from the object address is + * reported in the offsets array. * The object references may be buffered, so the callback may be invoked * multiple times for the same object: in all but the first call, the size * argument will be zero. diff --git a/mono/metadata/sgen-marksweep.c b/mono/metadata/sgen-marksweep.c index 288ff4178f3..ed79efa7b59 100644 --- a/mono/metadata/sgen-marksweep.c +++ b/mono/metadata/sgen-marksweep.c @@ -968,8 +968,14 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue) old_obj = obj; obj = copy_object_no_checks (obj, queue); if (G_UNLIKELY (old_obj == obj)) { - /*He have yet to figure out how to handle OOM failure during major evacuation*/ - g_assert (ptr_in_nursery (obj)); + /*If we fail to evacuate an object we just stop doing it for a given block size as all other will surely fail too.*/ + if (!ptr_in_nursery (obj)) { + int size_index; + block = MS_BLOCK_FOR_OBJ (obj); + size_index = block->obj_size_index; + evacuate_block_obj_sizes [size_index] = FALSE; + MS_MARK_OBJECT_AND_ENQUEUE (obj, block, queue); + } return; } *ptr = obj; diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c index ba5f090bd40..253402a31cb 100644 --- a/mono/metadata/threadpool.c +++ b/mono/metadata/threadpool.c @@ -1954,7 +1954,7 @@ async_invoke_thread (gpointer data) if (ar) { InterlockedIncrement (&tp->busy_threads); domain = ((MonoObject *)ar)->vtable->domain; -#ifndef DISABLE_SOCKET +#ifndef DISABLE_SOCKETS klass = ((MonoObject *) data)->vtable->klass; is_io_task = !is_corlib_asyncresult (domain, klass); is_socket = FALSE; diff --git a/mono/mini/CMakeLists.txt b/mono/mini/CMakeLists.txt deleted file mode 100644 index d748fbd39db..00000000000 --- a/mono/mini/CMakeLists.txt +++ /dev/null @@ -1,694 +0,0 @@ - -# Last synched with Makefile.am at r134597 - -cmake_policy(SET CMP0010 NEW) - -# Helper functions - -function(add_cs_target target sources args depends) - separate_arguments(sources) - separate_arguments(args) - separate_arguments(depends) - add_custom_command( - OUTPUT ${target} - COMMAND ${MCS} -out:${target} ${args} ${sources} - DEPENDS ${sources} ${depends} - ) - add_custom_target (${target}-target DEPENDS ${target}) -endfunction() - -function(add_cs_dll target sources args depends) - add_cs_target(${target} ${sources} "-target:library ${args}" "${depends}") -endfunction() - -function(add_cs_exe target sources args depends) - add_cs_target(${target} ${sources} "-target:exe ${args}" "${depends}") -endfunction() - -function(add_il_target target sources args) - separate_arguments(sources) - separate_arguments(args) - add_custom_command( - OUTPUT ${target} - COMMAND ${ILASM} -output=${target} ${args} ${sources} - DEPENDS ${sources} - ) - add_custom_target (${target}-target DEPENDS ${target}) -endfunction() - - - - -set(count 100000) -set(mtest for_loop) -set(monodir ${top_builddir}) - -set(CLASS ${mcs_topdir}/class/lib/net_2_0) - -set(RUNTIME MONO_PATH=${CLASS} ${top_builddir}/runtime/mono-wrapper) -set(RUNTIME_AOTCHECK MONO_PATH=${CLASS}:. ${top_builddir}/runtime/mono-wrapper) - -set(MCS ${RUNTIME} ${CLASS}/gmcs.exe -unsafe -nowarn:0162) -set(ILASM ${RUNTIME} ${CLASS}/ilasm.exe) - -set(x86_sources - mini-x86.c - mini-x86.h - exceptions-x86.c - tramp-x86.c) - -set(amd64_sources - mini-amd64.c - mini-amd64.h - exceptions-amd64.c - tramp-amd64.c) - -set(ppc_sources - mini-ppc.c - mini-ppc.h - exceptions-ppc.c - tramp-ppc.c) - -set(arm_sources - mini-arm.c - mini-arm.h - exceptions-arm.c - tramp-arm.c) - -set(mips_sources - mini-mips.c - mini-mips.h - exceptions-mips.c - tramp-mips.c) - -set(sparc_sources - mini-sparc.c - mini-sparc.h - exceptions-sparc.c - tramp-sparc.c) - -set(s390_sources - mini-s390.c - mini-s390.h - exceptions-s390.c - tramp-s390.c) - -set(s390x_sources - mini-s390x.c - mini-s390x.h - exceptions-s390x.c - tramp-s390x.c) - -set(ia64_sources - mini-ia64.c - mini-ia64.h - exceptions-ia64.c - tramp-ia64.c) - -set(alpha_sources - mini-alpha.c - mini-alpha.h - exceptions-alpha.c - tramp-alpha.c) - -set(hppa_sources - mini-hppa.c - mini-hppa.h - exceptions-hppa.c - tramp-hppa.c) - -set(darwin_sources - mini-darwin.c) - -set(windows_sources - mini-windows.c) - -set(posix_sources - mini-posix.c) - -set(common_sources - mini.c - ir-emit.h - method-to-ir.c - decompose.c - mini.h - version.h - optflags-def.h - jit-icalls.h - jit-icalls.c - trace.c - trace.h - patch-info.h - mini-ops.h - mini-arch.h - dominators.c - cfold.c - regalloc.c - regalloc.h - helpers.c - liveness.c - ssa.c - abcremoval.c - abcremoval.h - ssapre.c - ssapre.h - local-propagation.c - driver.c - debug-mini.c - debug-mini.h - linear-scan.c - aot-compiler.c - aot-runtime.c - graph.c - mini-codegen.c - mini-exceptions.c - mini-trampolines.c - declsec.c - declsec.h - wapihandles.c - branch-opts.c - mini-generic-sharing.c - regalloc2.c - simd-methods.h - tasklets.c - tasklets.h - simd-intrinsics.c - unwind.h - unwind.c - image-writer.h - image-writer.c - dwarfwriter.h - dwarfwriter.c - mini-gc.h - mini-gc.c) - -set(test_sources - basic-calls.cs - basic-long.cs - bench.cs - objects.cs - arrays.cs - basic-float.cs - basic-math.cs - basic.cs - exceptions.cs - devirtualization.cs - iltests.il.in - test.cs - generics.cs - generics-variant-types.il - basic-simd.cs) - -if(MONO_DEBUGGER_SUPPORTED) -if(PLATFORM_DARWIN) -set(mono_debugger_arch_sources mdb-debug-info32-darwin.s) -elseif(AMD64) -set(mono_debugger_arch_sources mdb-debug-info64.s) -elseif(X86) -set(mono_debugger_arch_sources mdb-debug-info32.s) -endif() -enable_language(ASM-ATT) -set(mono_debugger_sources debug-debugger.c debug-debugger.h ${mono_debugger_arch_sources}) - -set(ASM-ATT_FLAGS) -else(MONO_DEBUGGER_SUPPORTED) -set(mono_debugger_sources) -endif(MONO_DEBUGGER_SUPPORTED) - -set(regtests basic.exe basic-float.exe basic-long.exe basic-calls.exe objects.exe arrays.exe basic-math.exe exceptions.exe iltests.exe devirtualization.exe generics.exe basic-simd.exe) - -if(X86) -set(arch_sources ${x86_sources} ${mono_debugger_sources}) -set(arch_built cpu-x86.h) -set(arch_define __i386__) -endif() - -if(AMD64) -set(arch_sources ${amd64_sources} ${mono_debugger_sources}) -set(arch_built cpu-amd64.h) -set(arch_define __x86_64__) -endif() - -if(POWERPC) -set(arch_sources ${ppc_sources}) -set(arch_built cpu-ppc.h) -set(arch_define __ppc__) -endif() - -if(POWERPC64) -set(arch_sources ${ppc_sources}) -set(arch_built cpu-ppc64.h) -set(arch_define __ppc64__) -endif() - -if(MIPS) -set(arch_sources ${mips_sources}) -set(arch_built cpu-mips.h) -set(arch_define __mips__) -endif() - -if(ARM) -# pick up arm_dpimacros.h and arm_fpamacros.h -set(ARCH_CFLAGS -I../arch/arm) -set(arch_sources ${arm_sources}) -set(arch_built cpu-arm.h) -set(arch_define __arm__) -endif() - -if(SPARC) -set(arch_sources ${sparc_sources}) -set(arch_built cpu-sparc.h) -set(arch_define __sparc__) -endif() - -if(SPARC64) -set(arch_sources ${sparc_sources}) -set(arch_built cpu-sparc.h) -set(arch_define __sparc__) -endif() - -if(S390) -set(arch_sources ${s390_sources}) -set(arch_built cpu-s390.h) -set(arch_define __s390__) -endif() - -if(S390x) -set(arch_sources ${s390x_sources}) -set(arch_built cpu-s390x.h) -set(arch_define __s390__) -endif() - -if(IA64) -set(arch_sources ${ia64_sources}) -set(arch_built cpu-ia64.h) -set(arch_define __ia64__) -endif() - -if(ALPHA) -set(arch_sources ${alpha_sources} ${mono_debugger_sources}) -set(arch_built cpu-alpha.h) -set(arch_define __alpha__) -endif() - -if(HPPA) -# Only support 32-bit targets for now -set(arch_sources ${hppa_sources}) -set(arch_built cpu-hppa.h) -set(arch_define __hppa__) -endif() - -if(HOST_WIN32) -set(os_sources ${windows_sources}) -set(monobin_platform_ldflags) -endif() - -if(PLATFORM_SIGPOSIX) -set(os_sources ${posix_sources}) -set(monobin_platform_ldflags) -endif() - -if(PLATFORM_DARWIN) -set(os_sources ${darwin_sources} ${posix_sources}) -set(monobin_platform_ldflags "-sectcreate __TEXT __info_plist ${top_srcdir}/mono/mini/Info.plist") -endif() - -#### we don't always use the perl impl because it's an additional -#### build dependency for the poor windows users -#### ${arch_define} is the preprocessor symbol that enables all the opcodes -#### for the specific platform in mini-ops.h -###if CROSS_COMPILING -###GENMDESC_PRG=perl ${srcdir)/genmdesc.pl ${arch_define} ${srcdir) -###else !CROSS_COMPILING -set(GENMDESC_PRG ${CMAKE_CURRENT_BINARY_DIR}/genmdesc) -###endif !CROSS_COMPILING - -function(add_genmdesc_target target source define) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target} - COMMAND ${GENMDESC_PRG} ${CMAKE_CURRENT_BINARY_DIR}/${target} ${define} ${source} - DEPENDS genmdesc ${source} - ) -endfunction() - -foreach(arch x86 amd64 sparc ia64 alpha hppa mips) - add_genmdesc_target(cpu-${arch}.h cpu-${arch}.md ${arch}_desc) -endforeach() - -add_genmdesc_target(cpu-ppc.h cpu-ppc.md ppcg4) -add_genmdesc_target(cpu-ppc64.h cpu-ppc64.md ppc64_cpu_desc) -add_genmdesc_target(cpu-arm.h cpu-arm.md arm_cpu_desc) -add_genmdesc_target(cpu-s390.h cpu-s390.md s390_cpu_desc) -add_genmdesc_target(cpu-s390x.h cpu-s390x.md s390x_cpu_desc) - -include_directories(../..) -include_directories(${GLIB2_INCLUDE_DIRS}) -include_directories(${LIBGC_INCLUDE_DIRS}) -# FIXME: -link_directories(../../libgc/.libs) -set(CMAKE_C_FLAGS "${CFLAGS} ${LIBGC_CFLAGS} ${CPPFLAGS}") - -# genmdesc -add_executable(genmdesc genmdesc.c helpers.c) -target_link_libraries(genmdesc monoutils-static monoruntime-static ${GLIB2_LIBRARIES}) - -# libmono - -set(libmono_la_SOURCES ${common_sources} ${llvm_sources} ${arch_sources} ${os_sources}) - -# FIXME: cmake doesn't seem to recognize the ${arch_built} dependency -add_library(libmono-static STATIC ${libmono_la_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/${arch_built}) -target_link_libraries(libmono-static monoruntime-static monoutils-static monogc-static wapi-static ${GLIB2_LIBRARIES} ${LIBS}) -set_target_properties(libmono-static PROPERTIES OUTPUT_NAME "mono-static") - -# Since cmake has no support for convenience libraries, we have to link the -# final libmono.a ourselves, similarly to how libtool does it -add_custom_target(libmono.a - COMMAND rm -rf .libs/tmp libmono.a - COMMAND mkdir -p .libs/tmp/{1,2,3,4,5} - COMMAND cd .libs/tmp/1 && ar x ../../../../metadata/libmonoruntime-static.a - COMMAND cd .libs/tmp/2 && ar x ../../../../utils/libmonoutils-static.a - COMMAND cd .libs/tmp/3 && ar x ../../../../io-layer/libwapi-static.a - COMMAND cd .libs/tmp/3 && ar x ../../../../mini/libmono-static.a - COMMAND cd .libs/tmp/4 && ar x ../../../../../libgc/libmonogc-static.a - COMMAND ar r libmono.a `find .libs/tmp/ -name '*.o'` -) - -# FIXME: cmake has no support for convenience libraries, so we would end up -# creating a lot of shared libraries linking to each other -#add_library(libmono SHARED ${libmono_la_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/${arch_built}) -#set_target_properties(libmono PROPERTIES OUTPUT_NAME "mono") -#target_link_libraries(libmono monoruntime monoutils monogc wapi ${GLIB2_LIBRARIES} ${LIBS}) - -# version.h - -# Its a pain to try to pass a complex shell script to add_custom_command (), so -# write it to disk instead -# " needs to be escaped as \" -# \ needs to be escaped as \\ -set(top_srcdir ../../) -file(WRITE create-version.h.sh " - if test -d ${top_srcdir}/.git/svn; then svn_info=\"git log --no-color --first-parent -n1 --grep=git-svn-id: --pretty=format:%b | sed -n -e 's,git-svn-id: \\(.*\\)@\\(.*\\) .*,URL: \\1 Revision: \\2,p'\"; fi; - if test -d ${srcdir}/.svn; then svn_info='svn info'; fi; - if test -n \"$svn_info\"; then - (cd ${top_srcdir}; - LANG=C; export LANG; - branch=`eval $$svn_info | sed -n -e '/URL/ s,.*source/\\(.*\\)/mono.*,/\\1/mono,p'`; - version=`eval $$svn_info | sed -n -e '/Revision/ s/.*: //p'`; - echo \"#define FULL_VERSION \\\"$branch r$version\\\"\"; - ); - else - echo \"#define FULL_VERSION \\\"tarball\\\"\"; - fi > version.h -") - -# FIXME: dependencies ? -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h - COMMAND chmod a+x ./create-version.h.sh - COMMAND ./create-version.h.sh - VERBATIM -) - -# buildver.h - -# We build this after libmono was built so it contains the date when the final -# link was done -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/buildver.h - PRE_LINK - COMMAND sh -c "X='\"'; echo \"const char *build_date = $X`date`$X;\" > ${CMAKE_CURRENT_BINARY_DIR}/buildver.h" - DEPENDS libmono-static - VERBATIM -) -set_source_files_properties(main.c PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/buildver.h) -set_source_files_properties(main.c PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/buildver.h) - -# mono - -add_executable(mono main.c ${CMAKE_CURRENT_BINARY_DIR}/buildver.h) -add_dependencies(mono libmono-static) -target_link_libraries(mono libmono-static ${GLIB2_LIBRARIES}) - -install( - TARGETS mono - RUNTIME DESTINATION bin) - -# FIXME: Can't specify a dependency on libmono.a, and we don't want to build -# libmono.a until needed -install( - FILES libmono.a DESTINATION lib) - -# Test file targets - -foreach(test ${test_sources}) - if (${test} MATCHES ".*\\.cs") - string(REPLACE ".cs" ".exe" exe_name ${test}) - add_cs_exe(${exe_name} ${test} "-r:TestDriver.dll -r:generics-variant-types.dll -r:Mono.Simd.dll" "TestDriver.dll generics-variant-types.dll") - endif() -endforeach() - -set(il_source "iltests.il") -set(exe_name "iltests.exe") -add_custom_command( - OUTPUT ${exe_name} - COMMAND ${ILASM} -output=${exe_name} ${il_source} - DEPENDS ${il_source} - ) -add_custom_target(${exe_name}-exe DEPENDS ${exe_name}) - -add_custom_command( - OUTPUT "iltests.il" - COMMAND echo // DO NOT EDIT: This file has been generated from iltests.il.in > iltests.il - COMMAND cpp -Darch=${arch_define} < iltests.il.in | sed "s/^#.*//" >> iltests.il - DEPENDS iltests.il.in - VERBATIM -) - -add_cs_dll("TestDriver.dll" "TestDriver.cs" "-r:System.dll -r:System.dll" "") - -add_il_target("generics-variant-types.dll" "generics-variant-types.il" "-dll") - -# Testing targets - -add_custom_target(rcheck - COMMAND ${RUNTIME} --regression ${regtests} - DEPENDS mono ${regtests} -) - -# FIXME: make runs rcheck, but then says: 'No rule to make target `rcheck', needed by `mono/mini/CMakeFiles/check' -#add_custom_target(check -# DEPENDS rcheck) -add_custom_target(check - COMMAND ${RUNTIME} --regression ${regtests} - DEPENDS mono ${regtests} -) - -add_custom_target(testi - COMMAND ${RUNTIME} -v -v --ncompile 1 --compile Test:${mtest} test.exe - DEPENDS mono test.exe -) - -# ensure the tests are actually correct -add_custom_target(checktests - COMMAND for i in ${regtests}\; do ${RUNTIME} $$i\; done - DEPENDS ${regtests} -) - -add_custom_target(aotcheck - COMMAND rm -f *.exe.so - COMMAND ${RUNTIME} --aot ${regtests} || exit 1 - COMMAND for i in ${regtests}\; do ${RUNTIME_AOTCHECK} --regression $$i || exit 1\; done - COMMAND rm -f *.exe.so - DEPENDS mono ${regtests} -) - -# This currently only works on amd64/arm -add_custom_target(fullaotcheck - COMMAND rm -rf fullaot-tmp - COMMAND mkdir fullaot-tmp - COMMAND 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/ - COMMAND cp ${regtests} fullaot-tmp/ - COMMAND MONO_PATH=fullaot-tmp ${top_builddir}/runtime/mono-wrapper --aot=full fullaot-tmp/* || exit 1 - COMMAND for i in ${regtests}\; do echo $$i\; MONO_PATH=fullaot-tmp ${top_builddir}/runtime/mono-wrapper --full-aot fullaot-tmp/$$i --exclude '!FULLAOT' || exit 1\; done - DEPENDS mono ${regtests} -) - -add_custom_target(bench - COMMAND time env ${RUNTIME} --ncompile ${count} --compile Test:${mtest} test.exe - DEPENDS mono test.exe -) - -add_custom_target(stat1 - COMMAND ${RUNTIME} --verbose --statfile stats.pl --regression bench.exe - COMMAND perl viewstat.pl stats.pl - DEPENDS mono bench.exe -) - -add_custom_target(stat2 - COMMAND ${RUNTIME} --verbose --statfile stats.pl --regression basic.exe - COMMAND perl viewstat.pl -e stats.pl - DEPENDS mono basic.exe -) - -add_custom_target(stat3 - COMMAND ${RUNTIME} --statfile stats.pl --ncompile 1000 --compile Tests:test_0_many_nested_loops bench.exe - COMMAND perl viewstat.pl stats.pl - DEPENDS mono bench.exe -) - -#### This is needed for automake dependency generation -###if INCLUDED_LIBGC -###libgc_libs=${monodir)/libgc/libmonogc.la -###libgc_static_libs=${monodir)/libgc/libmonogc-static.la -###else -###libgc_libs=${LIBGC_LIBS) -###libgc_static_libs=${LIBGC_STATIC_LIBS) -###endif - -###AM_CFLAGS = \ -### -I${top_srcdir} \ -### ${LIBGC_CFLAGS) \ -### ${GLIB_CFLAGS) -### ${PLATFORM_CFLAGS} ${ARCH_CFLAGS) - -###AM_CXXFLAGS = ${LLVM_CXXFLAGS} ${GLIB_CFLAGS) - -###if PLATFORM_WIN32 -###export HOST_CC -#### The mingw math.h has "extern inline" functions that dont appear in libs, so -#### optimisation is required to actually inline them -###PLATFORM_CFLAGS = -O -###endif - -#### hack for automake to have the same source file in a library and a bin -###genmdesc_CFLAGS = ${AM_CFLAGS) - -###if NO_VERSION_SCRIPT -###monoldflags=${export_ldflags) -###monobinldflags=${export_ldflags) -###else -###monoldflags=-Wl,-version-script=${srcdir)/ldscript ${export_ldflags) -###monobinldflags=-Wl,-version-script=${srcdir)/ldscript.mono ${export_ldflags) -###endif - -###if PLATFORM_WIN32 -###libmono_la_LDFLAGS=-no-undefined -avoid-version -Wl,--kill-at ${monoldflags) -###else -###libmono_la_LDFLAGS=${monoldflags) -###endif - -###if JIT_SUPPORTED - -###if PLATFORM_WIN32 -###bin_PROGRAMS = mono monow -###else -###bin_PROGRAMS = mono -###endif - -###noinst_PROGRAMS = genmdesc - -###lib_LTLIBRARIES = libmono.la -###noinst_LTLIBRARIES = libmono-static.la -###endif - -###if DTRACE_G_REQUIRED -###LIBMONO_DTRACE_OBJECT = .libs/mono-dtrace.${OBJEXT) -###if STATIC_MONO -###MONO_DTRACE_OBJECT = mono-dtrace.${OBJEXT) -###else -###MONO_DTRACE_OBJECT = -###endif -###else -###MONO_DTRACE_OBJECT = -###LIBMONO_DTRACE_OBJECT = -###endif - -###if STATIC_MONO -#### Link libmono into mono statically -#### This leads to higher performance, especially with TLS -###MONO_LIB=libmono-static.la -###else -###MONO_LIB=libmono.la -###endif - -###mono_LDADD = \ -### ${MONO_LIB) \ -### ${GLIB_LIBS) \ -### ${LLVM_LIBS) \ -### -lm \ -### ${MONO_DTRACE_OBJECT) \ -### ${LLVM_LDFLAGS} - -###mono_LDFLAGS = \ -### ${static_flags} -export-dynamic ${monobinldflags) ${monobin_platform_ldflags} - -###if DTRACE_G_REQUIRED - -###mono-dtrace.${OBJEXT): ${top_srcdir)/data/mono.d mini.lo ${monodir)/mono/metadata/libmonoruntime-static.la -### DTRACE="${DTRACE)" DTRACEFLAGS="${DTRACEFLAGS)" AR="${AR)" ${SHELL} ${top_srcdir)/data/dtrace-prelink.sh \ -### $@ ${top_srcdir)/data/mono.d ${monodir)/mono/metadata/libmonoruntime-static.la mini.lo - -###.libs/mono-dtrace.${OBJEXT): ${top_srcdir)/data/mono.d mini.lo ${monodir)/mono/metadata/libmonoruntime.la -### DTRACE="${DTRACE)" DTRACEFLAGS="${DTRACEFLAGS)" AR="${AR)" ${SHELL} ${top_srcdir)/data/dtrace-prelink.sh \ -### --pic $@ ${top_srcdir)/data/mono.d ${monodir)/mono/metadata/libmonoruntime.la mini.lo - -###endif - -#### Create monow.exe, linked for the 'windows' subsystem -###if PLATFORM_WIN32 -###monow_LDADD = ${mono_LDADD) -###monow_LDFLAGS = ${mono_LDFLAGS} -mwindows -###monow_SOURCES = ${mono_SOURCES) -###endif - -#### Don't link this against libmonoruntime to speed up rebuilds -###genmdesc_LDADD = \ -### ${monodir)/mono/utils/libmonoutils.la ${monodir)/mono/metadata/opcodes.lo -lm \ -### ${GLIB_LIBS) - -###if ENABLE_LLVM -#### Disabled for now to fix the windows build -####llvm_sources = \ -#### mini-llvm.c \ -#### mini-llvm-cpp.cpp -###endif - -###libmono_static_la_LIBADD = ${static_libs} ${MONO_DTRACE_OBJECT) - -###libmonoincludedir = ${includedir)/mono-${API_VER)/mono/jit - -###libmonoinclude_HEADERS = jit.h - -###libmono_la_LIBADD = \ -### ${libs} ${LIBMONO_DTRACE_OBJECT) - -###clean-local: -### rm -f mono a.out gmon.out *.o buildver.h test.exe - -###pkgconfigdir = ${libdir)/pkgconfig - -###if JIT_SUPPORTED -###BUILT_SOURCES = version.h ${arch_built) -###else -###BUILT_SOURCES = version.h -###endif - -###CLEANFILES= ${BUILT_SOURCES} *.exe *.dll -###EXTRA_DIST = TestDriver.cs ldscript ldscript.mono \ -### genmdesc.pl \ -### ${test_sources} \ -### ${x86_sources} cpu-x86.md \ -### ${amd64_sources} cpu-amd64.md \ -### ${ppc_sources} cpu-ppc.md cpu-ppc64.md \ -### ${arm_sources} cpu-arm.md \ -### ${mips_sources} cpu-mips.md \ -### ${sparc_sources} cpu-sparc.md \ -### ${s390_sources} cpu-s390.md \ -### ${s390x_sources} cpu-s390x.md \ -### ${ia64_sources} cpu-ia64.md \ -### ${alpha_sources} cpu-alpha.md \ -### ${hppa_sources} cpu-hppa.md \ -### ${windows_sources) \ -### ${darwin_sources) Info.plist \ -### ${posix_sources) diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index ca53b586623..7515c6ac0f3 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -2846,6 +2846,34 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method) return code; } + /* Same for CompareExchange */ + if (method_index == 0xffffff && method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE && method->klass->image == mono_defaults.corlib && !strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Interlocked") && !strcmp (method->name, "CompareExchange")) { + MonoMethod *m; + MonoGenericContext ctx; + MonoType *args [16]; + gpointer iter = NULL; + + while ((m = mono_class_get_methods (method->klass, &iter))) { + if (mono_method_signature (m)->generic_param_count && !strcmp (m->name, "CompareExchange")) + break; + } + g_assert (m); + + memset (&ctx, 0, sizeof (ctx)); + args [0] = &mono_defaults.object_class->byval_arg; + ctx.method_inst = mono_metadata_get_generic_inst (1, args); + + m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method (m, &ctx), TRUE, TRUE); + + /* + * Get the code for the instantiation which should be emitted into + * the mscorlib aot image by the AOT compiler. + */ + code = mono_aot_get_method (domain, m); + if (code) + return code; + } + if (method_index == 0xffffff && method->is_inflated && mono_method_is_generic_sharable_impl_full (method, FALSE, TRUE)) { /* Partial sharing */ method_index = find_extra_method (mini_get_shared_method (method), &amodule); diff --git a/mono/mini/driver.c b/mono/mini/driver.c index de8050e4f2c..ce4d492a4d1 100644 --- a/mono/mini/driver.c +++ b/mono/mini/driver.c @@ -313,6 +313,7 @@ opt_sets [] = { MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_CFOLD, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS, + MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_TAILC, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_SSA, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_CMOV, @@ -1437,7 +1438,11 @@ mono_main (int argc, char* argv[]) GString *path = g_string_new (argv [0]); g_string_append (path, "-sgen"); argv [0] = path->str; +#ifdef HAVE_EXECVP execvp (path->str, argv); +#else + fprintf (stderr, "Error: --gc= option not supported on this platform.\n"); +#endif } } else if (strcmp (argv [i], "--gc=boehm") == 0) { if (!strcmp (mono_gc_get_gc_name (), "sgen")) { @@ -1449,7 +1454,11 @@ mono_main (int argc, char* argv[]) } *p = 0; argv [0] = p; +#ifdef HAVE_EXECVP execvp (p, argv); +#else + fprintf (stderr, "Error: --gc= option not supported on this platform.\n"); +#endif } } else if (strcmp (argv [i], "--config") == 0) { if (i +1 >= argc){ diff --git a/mono/mini/exceptions.cs b/mono/mini/exceptions.cs index c44f0d063a3..b6c7a620899 100644 --- a/mono/mini/exceptions.cs +++ b/mono/mini/exceptions.cs @@ -2240,6 +2240,8 @@ class Tests { public static void rethrow2 () { rethrow1 (); + /* This disables tailcall opts */ + Console.WriteLine (); } } diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index ae7cd780e3c..00cd7de900d 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -284,6 +284,18 @@ mono_print_bb (MonoBasicBlock *bb, const char *msg) mono_print_ins_index (-1, tree); } +void +mono_create_helper_signatures (void) +{ + helper_sig_domain_get = mono_create_icall_signature ("ptr"); + helper_sig_class_init_trampoline = mono_create_icall_signature ("void"); + helper_sig_generic_class_init_trampoline = mono_create_icall_signature ("void"); + helper_sig_generic_class_init_trampoline_llvm = mono_create_icall_signature ("void 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"); +} + /* * Can't put this at the beginning, since other files reference stuff from this * file. @@ -5496,6 +5508,50 @@ is_jit_optimizer_disabled (MonoMethod *m) return val; } +static gboolean +is_supported_tail_call (MonoCompile *cfg, MonoMethod *method, MonoMethod *cmethod, MonoMethodSignature *fsig) +{ + gboolean supported_tail_call; + int i; + +#ifdef MONO_ARCH_USE_OP_TAIL_CALL + supported_tail_call = MONO_ARCH_USE_OP_TAIL_CALL (mono_method_signature (method), mono_method_signature (cmethod)); +#else + supported_tail_call = mono_metadata_signature_equal (mono_method_signature (method), mono_method_signature (cmethod)) && !MONO_TYPE_ISSTRUCT (mono_method_signature (cmethod)->ret); +#endif + + for (i = 0; i < fsig->param_count; ++i) { + if (fsig->params [i]->byref || fsig->params [i]->type == MONO_TYPE_PTR || fsig->params [i]->type == MONO_TYPE_FNPTR) + /* These can point to the current method's stack */ + supported_tail_call = FALSE; + } + if (fsig->hasthis && cmethod->klass->valuetype) + /* this might point to the current method's stack */ + supported_tail_call = FALSE; + if (cmethod->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) + supported_tail_call = FALSE; + if (cfg->method->save_lmf) + supported_tail_call = FALSE; + if (cmethod->wrapper_type && cmethod->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD) + supported_tail_call = FALSE; + + /* Debugging support */ +#if 0 + if (supported_tail_call) { + static int count = 0; + count ++; + if (getenv ("COUNT")) { + if (count == atoi (getenv ("COUNT"))) + printf ("LAST: %s\n", mono_method_full_name (cmethod, TRUE)); + if (count > atoi (getenv ("COUNT"))) + supported_tail_call = FALSE; + } + } +#endif + + return supported_tail_call; +} + /* * mono_method_to_ir: * @@ -6742,56 +6798,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b break; } -#ifdef MONO_ARCH_USE_OP_TAIL_CALL - supported_tail_call = cmethod && MONO_ARCH_USE_OP_TAIL_CALL (mono_method_signature (method), mono_method_signature (cmethod)); -#else - supported_tail_call = cmethod && mono_metadata_signature_equal (mono_method_signature (method), mono_method_signature (cmethod)) && !MONO_TYPE_ISSTRUCT (mono_method_signature (cmethod)->ret); -#endif - - /* Tail prefix */ - /* FIXME: runtime generic context pointer for jumps? */ - /* FIXME: handle this for generic sharing eventually */ - if ((ins_flag & MONO_INST_TAILCALL) && !cfg->generic_sharing_context && !vtable_arg && cmethod && (*ip == CEE_CALL) && supported_tail_call) { - MonoCallInst *call; - - /* Prevent inlining of methods with tail calls (the call stack would be altered) */ - INLINE_FAILURE; - -#ifdef MONO_ARCH_USE_OP_TAIL_CALL - /* Handle tail calls similarly to calls */ - call = mono_emit_call_args (cfg, mono_method_signature (cmethod), sp, FALSE, FALSE, TRUE); -#else - MONO_INST_NEW_CALL (cfg, call, OP_JMP); - call->tail_call = TRUE; - call->method = cmethod; - call->signature = mono_method_signature (cmethod); - - /* - * We implement tail calls by storing the actual arguments into the - * argument variables, then emitting a CEE_JMP. - */ - for (i = 0; i < n; ++i) { - /* Prevent argument from being register allocated */ - arg_array [i]->flags |= MONO_INST_VOLATILE; - EMIT_NEW_ARGSTORE (cfg, ins, i, sp [i]); - } -#endif - - ins = (MonoInst*)call; - ins->inst_p0 = cmethod; - ins->inst_p1 = arg_array [0]; - MONO_ADD_INS (bblock, ins); - link_bblock (cfg, bblock, end_bblock); - start_new_bblock = 1; - - CHECK_CFG_EXCEPTION; - - /* skip CEE_RET as well */ - ip += 6; - ins_flag = 0; - break; - } - /* * Implement a workaround for the inherent races involved in locking: * Monitor.Enter () @@ -7028,6 +7034,68 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b break; } + /* Tail prefix / tail call optimization */ + + /* FIXME: Enabling TAILC breaks some inlining/stack trace/etc tests */ + /* FIXME: runtime generic context pointer for jumps? */ + /* FIXME: handle this for generic sharing eventually */ + supported_tail_call = cmethod && + ((((ins_flag & MONO_INST_TAILCALL) && (*ip == CEE_CALL)) + ))//|| ((cfg->opt & MONO_OPT_TAILC) && *ip == CEE_CALL && ip [5] == CEE_RET)) + && !vtable_arg && !cfg->generic_sharing_context && is_supported_tail_call (cfg, method, cmethod, fsig); + + if (supported_tail_call) { + MonoCallInst *call; + + /* Prevent inlining of methods with tail calls (the call stack would be altered) */ + INLINE_FAILURE; + + //printf ("HIT: %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE)); + +#ifdef MONO_ARCH_USE_OP_TAIL_CALL + /* Handle tail calls similarly to calls */ + call = mono_emit_call_args (cfg, mono_method_signature (cmethod), sp, FALSE, FALSE, TRUE); +#else + MONO_INST_NEW_CALL (cfg, call, OP_JMP); + call->tail_call = TRUE; + call->method = cmethod; + call->signature = mono_method_signature (cmethod); + + /* + * We implement tail calls by storing the actual arguments into the + * argument variables, then emitting a CEE_JMP. + */ + for (i = 0; i < n; ++i) { + /* Prevent argument from being register allocated */ + arg_array [i]->flags |= MONO_INST_VOLATILE; + EMIT_NEW_ARGSTORE (cfg, ins, i, sp [i]); + } +#endif + + ins = (MonoInst*)call; + ins->inst_p0 = cmethod; + ins->inst_p1 = arg_array [0]; + MONO_ADD_INS (bblock, ins); + link_bblock (cfg, bblock, end_bblock); + start_new_bblock = 1; + + CHECK_CFG_EXCEPTION; + + ip += 5; + ins_flag = 0; + + // FIXME: Eliminate unreachable epilogs + + /* + * OP_TAILCALL has no return value, so skip the CEE_RET if it is + * only reachable from this call. + */ + GET_BBLOCK (cfg, tblock, ip); + if (tblock == bblock || tblock->in_count == 0) + ip += 1; + break; + } + /* Common call */ INLINE_FAILURE; if (vtable_arg) { @@ -11583,18 +11651,6 @@ mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts) g_free (live_range_end_bb); } -void -mono_create_helper_signatures (void) -{ - helper_sig_domain_get = mono_create_icall_signature ("ptr"); - helper_sig_class_init_trampoline = mono_create_icall_signature ("void"); - helper_sig_generic_class_init_trampoline = mono_create_icall_signature ("void"); - helper_sig_generic_class_init_trampoline_llvm = mono_create_icall_signature ("void 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"); -} - /** * FIXME: * - use 'iadd' instead of 'int_add' diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index b9c5b570f63..6d0aaf90512 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -882,6 +882,25 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit return args_size; } +gboolean +mono_amd64_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) +{ + CallInfo *c1, *c2; + gboolean res; + + c1 = get_call_info (NULL, NULL, caller_sig, FALSE); + c2 = get_call_info (NULL, NULL, callee_sig, FALSE); + res = c1->stack_usage >= c2->stack_usage; + if (callee_sig->ret && MONO_TYPE_ISSTRUCT (callee_sig->ret) && c2->ret.storage != ArgValuetypeInReg) + /* An address on the callee's stack is passed as the first argument */ + res = FALSE; + + g_free (c1); + g_free (c2); + + return res; +} + static int cpuid (int id, int* p_eax, int* p_ebx, int* p_ecx, int* p_edx) { @@ -4055,10 +4074,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } case OP_TAILCALL: { - /* - * Note: this 'frame destruction' logic is useful for tail calls, too. - * Keep in sync with the code in emit_epilog. - */ + MonoCallInst *call = (MonoCallInst*)ins; int pos = 0, i; /* FIXME: no tracing support... */ @@ -4076,20 +4092,32 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) save_offset += 8; } amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, cfg->arch.stack_alloc_size); + + // FIXME: + if (call->stack_usage) + NOT_IMPLEMENTED; } else { for (i = 0; i < AMD64_NREG; ++i) if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) pos -= sizeof (gpointer); - - if (pos) - amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, pos); - /* Pop registers in reverse order */ - for (i = AMD64_NREG - 1; i > 0; --i) + /* Restore callee-saved registers */ + for (i = AMD64_NREG - 1; i > 0; --i) { if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) { - amd64_pop_reg (code, i); + amd64_mov_reg_membase (code, i, AMD64_RBP, pos, 8); + pos += 8; } + } + + /* Copy arguments on the stack to our argument area */ + for (i = 0; i < call->stack_usage; i += 8) { + amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, i, 8); + amd64_mov_membase_reg (code, AMD64_RBP, 16 + i, AMD64_RAX, 8); + } + + if (pos) + amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, pos); amd64_leave (code); } diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index c2f8a863743..8a2da94a4fd 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -392,7 +392,10 @@ typedef struct { #define MONO_ARCH_HAVE_CARD_TABLE_WBARRIER 1 -#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_metadata_signature_equal ((caller_sig), (callee_sig)) +gboolean +mono_amd64_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) MONO_INTERNAL; + +#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_amd64_tail_call_supported (caller_sig, callee_sig) /* Used for optimization, not complete */ #define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE) diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index 0454997f72c..675461d1007 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -1485,9 +1485,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) } else if (!t->byref && (t->type == MONO_TYPE_R8)) { int creg; -#ifdef MONO_ARCH_SOFT_FLOAT - g_assert_not_reached (); -#endif + /* This should work for soft-float as well */ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, ARMREG_SP, (cfg->param_area - 8), in->dreg); creg = mono_alloc_ireg (cfg); @@ -4437,7 +4435,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) tracing = 1; sig = mono_method_signature (method); - cfg->code_size = 256 + sig->param_count * 20; + cfg->code_size = 256 + sig->param_count * 64; code = cfg->native_code = g_malloc (cfg->code_size); mono_emit_unwind_op_def_cfa (cfg, code, ARMREG_SP, 0); diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 5040275c448..28479b597b2 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -3245,6 +3245,11 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) switch (ins->opcode) { case OP_STOREV_MEMBASE: + if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) { + /* FIXME: Emit write barriers like in mini_emit_stobj () */ + LLVM_FAILURE (ctx, "storev_membase + write barriers"); + break; + } if (!addresses [ins->sreg1]) { /* SIMD */ g_assert (values [ins->sreg1]); @@ -3273,6 +3278,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) default: g_assert_not_reached (); } + CHECK_FAILURE (ctx); if (done) break; diff --git a/mono/profiler/decode.c b/mono/profiler/decode.c index 0a33040a73d..7c42a37dbd3 100644 --- a/mono/profiler/decode.c +++ b/mono/profiler/decode.c @@ -12,7 +12,7 @@ #include #include #include -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(__FreeBSD__) #include #endif #include @@ -42,6 +42,14 @@ static uint64_t time_to = 0xffffffffffffffffULL; static uint64_t startup_time = 0; static FILE* outfile = NULL; +static int32_t +read_int16 (unsigned char *p) +{ + int32_t value = *p++; + value |= (*p++) << 8; + return value; +} + static int32_t read_int32 (unsigned char *p) { @@ -239,6 +247,8 @@ struct _HeapClassDesc { HeapClassRevRef *rev_hash; int rev_hash_size; int rev_count; + uintptr_t pinned_references; + uintptr_t root_references; }; static int @@ -312,6 +322,10 @@ struct _HeapShot { HeapObjectDesc **objects_hash; uintptr_t objects_count; uintptr_t objects_hash_size; + uintptr_t num_roots; + uintptr_t *roots; + uintptr_t *roots_extra; + int *roots_types; }; static HeapShot *heap_shots = NULL; @@ -441,7 +455,7 @@ heap_shot_find_obj_slot (HeapShot *hs, uintptr_t objaddr) i = 0; } while (i != start_pos); /* should not happen */ - printf ("failed heap obj update\n"); + //printf ("failed heap obj slot\n"); return -1; } @@ -526,6 +540,81 @@ heap_shot_resolve_reverse_refs (HeapShot *hs) } } +#define MARK_GRAY 1 +#define MARK_BLACK 2 + +static void +heap_shot_mark_objects (HeapShot *hs) +{ + uintptr_t i, oi, r; + unsigned char *marks; + HeapObjectDesc *obj, *ref; + int marked_some; + uintptr_t num_marked = 0, num_unmarked; + for (i = 0; i < hs->num_roots; ++i) { + HeapClassDesc *cd; + oi = heap_shot_find_obj_slot (hs, hs->roots [i]); + if (oi == -1) { + continue; + } + obj = hs->objects_hash [oi]; + cd = obj->hklass; + if (hs->roots_types [i] & MONO_PROFILE_GC_ROOT_PINNING) + cd->pinned_references++; + cd->root_references++; + } + if (!debug) + return; + /* consistency checks: it seems not all the objects are walked in the heap in some cases */ + marks = calloc (hs->objects_hash_size, 1); + if (!marks) + return; + for (i = 0; i < hs->num_roots; ++i) { + oi = heap_shot_find_obj_slot (hs, hs->roots [i]); + if (oi == -1) { + fprintf (outfile, "root type 0x%x for obj %p (%s) not found in heap\n", hs->roots_types [i], (void*)hs->roots [i], lookup_class (hs->roots_extra [i])->name); + continue; + } + obj = hs->objects_hash [oi]; + if (!marks [oi]) { + marks [oi] = obj->num_refs? MARK_GRAY: MARK_BLACK; + num_marked++; + } + } + marked_some = 1; + while (marked_some) { + marked_some = 0; + for (i = 0; i < hs->objects_hash_size; ++i) { + if (marks [i] != MARK_GRAY) + continue; + marks [i] = MARK_BLACK; + obj = hs->objects_hash [i]; + for (r = 0; r < obj->num_refs; ++r) { + oi = heap_shot_find_obj_slot (hs, obj->refs [r]); + if (oi == -1) { + fprintf (outfile, "referenced obj %p not found in heap\n", (void*)obj->refs [r]); + continue; + } + ref = hs->objects_hash [oi]; + if (!marks [oi]) { + marks [oi] = ref->num_refs? MARK_GRAY: MARK_BLACK; + } + } + marked_some++; + } + } + + num_unmarked = 0; + for (i = 0; i < hs->objects_hash_size; ++i) { + if (hs->objects_hash [i] && !marks [i]) { + num_unmarked++; + fprintf (outfile, "object %p (%s) unmarked\n", (void*)hs->objects_hash [i], hs->objects_hash [i]->hklass->klass->name); + } + } + fprintf (outfile, "Total unmarked: %d/%d\n", num_unmarked, hs->objects_count); + free (marks); +} + static void heap_shot_free_objects (HeapShot *hs) { @@ -622,6 +711,8 @@ typedef struct { int version_major; int version_minor; int timer_overhead; + int pid; + int port; uint64_t startup_time; ThreadContext *threads; ThreadContext *current; @@ -641,6 +732,12 @@ struct _ThreadContext { int stack_size; int stack_id; HeapShot *current_heap_shot; + uintptr_t num_roots; + uintptr_t size_roots; + uintptr_t *roots; + uintptr_t *roots_extra; + int *roots_types; + uint64_t gc_start_times [3]; }; static void @@ -657,11 +754,19 @@ load_data (ProfContext *ctx, int size) { ensure_buffer (ctx, size); #if defined (HAVE_SYS_ZLIB) - if (ctx->gzfile) - return gzread (ctx->gzfile, ctx->buf, size) == size; - else + if (ctx->gzfile) { + int r = gzread (ctx->gzfile, ctx->buf, size); + if (r == 0) + return size == 0? 1: 0; + return r == size; + } else #endif - return fread (ctx->buf, size, 1, ctx->file); + { + int r = fread (ctx->buf, size, 1, ctx->file); + if (r == 0) + return size == 0? 1: 0; + return r; + } } static ThreadContext* @@ -785,6 +890,23 @@ add_trace_methods (MethodDesc **methods, int count, TraceDesc *trace, uint64_t v return bt; } +static void +thread_add_root (ThreadContext *ctx, uintptr_t obj, int root_type, uintptr_t extra_info) +{ + if (ctx->num_roots == ctx->size_roots) { + int new_size = ctx->size_roots * 2; + if (!new_size) + new_size = 4; + ctx->roots = realloc (ctx->roots, new_size * sizeof (uintptr_t)); + ctx->roots_extra = realloc (ctx->roots_extra, new_size * sizeof (uintptr_t)); + ctx->roots_types = realloc (ctx->roots_types, new_size * sizeof (int)); + ctx->size_roots = new_size; + } + ctx->roots_types [ctx->num_roots] = root_type; + ctx->roots_extra [ctx->num_roots] = extra_info; + ctx->roots [ctx->num_roots++] = obj; +} + static int compare_callc (const void *a, const void *b) { @@ -845,7 +967,6 @@ pop_method (ThreadContext *thread, MethodDesc *method, uint64_t timestamp) } typedef struct { - uint64_t start_time; /* move this per-thread? */ uint64_t total_time; uint64_t max_time; int count; @@ -953,6 +1074,19 @@ get_handle_name (int htype) } } +static const char* +get_root_name (int rtype) +{ + switch (rtype & MONO_PROFILE_GC_ROOT_TYPEMASK) { + case MONO_PROFILE_GC_ROOT_STACK: return "stack"; + case MONO_PROFILE_GC_ROOT_FINALIZER: return "finalizer"; + case MONO_PROFILE_GC_ROOT_HANDLE: return "handle"; + case MONO_PROFILE_GC_ROOT_OTHER: return "other"; + case MONO_PROFILE_GC_ROOT_MISC: return "misc"; + default: return "unknown"; + } +} + static MethodDesc** decode_bt (MethodDesc** sframes, int *size, unsigned char *p, unsigned char **endp, intptr_t ptr_base) { @@ -1057,8 +1191,13 @@ decode_buffer (ProfContext *ctx) if (!load_data (ctx, 48)) return 0; p = ctx->buf; - if (read_int32 (p) != BUF_ID) + if (read_int32 (p) != BUF_ID) { + fprintf (outfile, "Incorrect buffer id: 0x%x\n", read_int32 (p)); + for (i = 0; i < 48; ++i) { + fprintf (outfile, "0x%x%s", p [i], i % 8?" ":"\n"); + } return 0; + } len = read_int32 (p + 4); time_base = read_int64 (p + 8); ptr_base = read_int64 (p + 16); @@ -1101,16 +1240,16 @@ decode_buffer (ProfContext *ctx) uint64_t ev = decode_uleb128 (p, &p); int gen = decode_uleb128 (p, &p); if (debug) - fprintf (outfile, "gc event for gen%d: %s at %llu\n", gen - 1, gc_event_name (ev), time_base); + fprintf (outfile, "gc event for gen%d: %s at %llu (thread: 0x%x)\n", gen, gc_event_name (ev), time_base, thread->thread_id); if (gen > 2) { fprintf (outfile, "incorrect gc gen: %d\n", gen); break; } if (ev == MONO_GC_EVENT_START) { - gc_info [gen].start_time = time_base; + thread->gc_start_times [gen] = time_base; gc_info [gen].count++; } else if (ev == MONO_GC_EVENT_END) { - tdiff = time_base - gc_info [gen].start_time; + tdiff = time_base - thread->gc_start_times [gen]; gc_info [gen].total_time += tdiff; if (tdiff > gc_info [gen].max_time) gc_info [gen].max_time = tdiff; @@ -1286,6 +1425,7 @@ decode_buffer (ProfContext *ctx) uint64_t size = decode_uleb128 (p, &p); uintptr_t num = decode_uleb128 (p, &p); uintptr_t ref_offset; + uintptr_t last_obj_offset = 0; ClassDesc *cd = lookup_class (ptr_base + ptrdiff); if (size) { HeapClassDesc *hcd = add_heap_shot_class (thread->current_heap_shot, cd, size); @@ -1302,7 +1442,9 @@ decode_buffer (ProfContext *ctx) /* FIXME: use object distance to measure how good * the GC is at keeping related objects close */ + uintptr_t offset = ctx->data_version > 1? last_obj_offset + decode_uleb128 (p, &p): -1; intptr_t obj1diff = decode_sleb128 (p, &p); + last_obj_offset = offset; if (collect_traces) ho->refs [ref_offset + i] = OBJ_ADDR (obj1diff); if (num_tracked_objects) @@ -1310,6 +1452,20 @@ decode_buffer (ProfContext *ctx) } if (debug && size) fprintf (outfile, "traced object %p, size %llu (%s), refs: %d\n", (void*)OBJ_ADDR (objdiff), size, cd->name, num); + } else if (subtype == TYPE_HEAP_ROOT) { + uintptr_t num = decode_uleb128 (p + 1, &p); + uintptr_t gc_num = decode_uleb128 (p, &p); + int i; + for (i = 0; i < num; ++i) { + intptr_t objdiff = decode_sleb128 (p, &p); + int root_type = decode_uleb128 (p, &p); + /* we just discard the extra info for now */ + uintptr_t extra_info = decode_uleb128 (p, &p); + if (debug) + fprintf (outfile, "object %p is a %s root\n", (void*)OBJ_ADDR (objdiff), get_root_name (root_type)); + if (collect_traces) + thread_add_root (thread, OBJ_ADDR (objdiff), root_type, extra_info); + } } else if (subtype == TYPE_HEAP_END) { uint64_t tdiff = decode_uleb128 (p + 1, &p); LOG_TIME (time_base, tdiff); @@ -1317,8 +1473,26 @@ decode_buffer (ProfContext *ctx) if (debug) fprintf (outfile, "heap shot end\n"); if (collect_traces) { - heap_shot_resolve_reverse_refs (thread->current_heap_shot); - heap_shot_free_objects (thread->current_heap_shot); + HeapShot *hs = thread->current_heap_shot; + if (hs && thread->num_roots) { + /* transfer the root ownershipt to the heapshot */ + hs->num_roots = thread->num_roots; + hs->roots = thread->roots; + hs->roots_extra = thread->roots_extra; + hs->roots_types = thread->roots_types; + } else { + free (thread->roots); + free (thread->roots_extra); + free (thread->roots_types); + } + thread->num_roots = 0; + thread->size_roots = 0; + thread->roots = NULL; + thread->roots_extra = NULL; + thread->roots_types = NULL; + heap_shot_resolve_reverse_refs (hs); + heap_shot_mark_objects (hs); + heap_shot_free_objects (hs); } thread->current_heap_shot = NULL; } else if (subtype == TYPE_HEAP_START) { @@ -1463,12 +1637,13 @@ load_file (char *name) exit (1); } #if defined (HAVE_SYS_ZLIB) - ctx->gzfile = gzdopen (fileno (ctx->file), "rb"); + if (ctx->file != stdin) + ctx->gzfile = gzdopen (fileno (ctx->file), "rb"); #endif if (!load_data (ctx, 32)) return NULL; p = ctx->buf; - if (read_int32 (p) != LOG_HEADER_ID || p [6] != LOG_DATA_VERSION) + if (read_int32 (p) != LOG_HEADER_ID || p [6] > LOG_DATA_VERSION) return NULL; ctx->version_major = p [4]; ctx->version_minor = p [5]; @@ -1480,6 +1655,8 @@ load_file (char *name) return NULL; ctx->startup_time = read_int64 (p + 8); ctx->timer_overhead = read_int32 (p + 16); + ctx->pid = read_int32 (p + 24); + ctx->port = read_int16 (p + 28); return ctx; } @@ -1518,7 +1695,11 @@ dump_header (ProfContext *ctx) fprintf (outfile, "\tProfiler version: %d.%d\n", ctx->version_major, ctx->version_minor); fprintf (outfile, "\tData version: %d\n", ctx->data_version); fprintf (outfile, "\tMean timer overhead: %d nanoseconds\n", ctx->timer_overhead); - fprintf (outfile, "\tProgram startup: %s\n", t); + fprintf (outfile, "\tProgram startup: %s", t); + if (ctx->pid) + fprintf (outfile, "\tProgram ID: %d\n", ctx->pid); + if (ctx->port) + fprintf (outfile, "\tServer listening on: %d\n", ctx->port); } static void @@ -1822,8 +2003,8 @@ heap_shot_summary (HeapShot *hs, int hs_num, HeapShot *last_hs) } hs->sorted = sorted; qsort (sorted, ccount, sizeof (void*), compare_heap_class); - fprintf (outfile, "\n\tHeap shot %d at %.3f secs: size: %llu, object count: %llu, class count: %d\n", - hs_num, (hs->timestamp - startup_time)/1000000000.0, size, count, ccount); + fprintf (outfile, "\n\tHeap shot %d at %.3f secs: size: %llu, object count: %llu, class count: %d, roots: %d\n", + hs_num, (hs->timestamp - startup_time)/1000000000.0, size, count, ccount, hs->num_roots); if (!verbose && ccount > 30) ccount = 30; fprintf (outfile, "\t%10s %10s %8s Class name\n", "Bytes", "Count", "Average"); @@ -1852,6 +2033,8 @@ heap_shot_summary (HeapShot *hs, int hs_num, HeapShot *last_hs) } assert (cd->rev_count == k); qsort (rev_sorted, cd->rev_count, sizeof (HeapClassRevRef), compare_rev_class); + if (cd->root_references) + fprintf (outfile, "\t\t%d root references (%d pinning)\n", cd->root_references, cd->pinned_references); dump_rev_claases (rev_sorted, cd->rev_count); free (rev_sorted); } diff --git a/mono/profiler/log-profiler.txt b/mono/profiler/log-profiler.txt index 0d6349b6f24..b44b3eda9dd 100644 --- a/mono/profiler/log-profiler.txt +++ b/mono/profiler/log-profiler.txt @@ -80,20 +80,19 @@ and exception throws) a stack trace is collected by default. See the *maxframes* control this behaviour. *calls* enables method enter/leave events if they were disabled by another option like *heapshot*. -* *heapshot*: collect heap shot data at each major collection. The frequency of the -heap shots can be changed with the *hsmode* option below. When this option is used +* *heapshot[=MODE]*: collect heap shot data at each major collection. The frequency of the +heap shots can be changed with the *MODE* parameter. When this option is used allocation events and method enter/leave events are not recorded by default: if they are needed, they need to be enabled explicitly. - -* *hsmode=MODE*: modify the default heap shot frequency according to MODE. -hsmode can be used multiple times with different modes: in that case a heap shot is +The optional parameter *MODE* can modify the default heap shot frequency. +heapshot can be used multiple times with different modes: in that case a heap shot is taken if either of the conditions are met. MODE can be one of: * *NUM*ms: perform a heap shot if at least *NUM* milliseconds passed since the last one. - * *NUM*gc: perform a heap shot every *NUM* garbage collections (either - minor or major). - + * *NUM*gc: perform a heap shot every *NUM* major garbage collections + * *ondemand*: perform a heap shot when such a command is sent to the + control port * *time=TIMER*: use the TIMER timestamp mode. TIMER can have the following values: * *fast*: a usually faster but possibly more inaccurate timer @@ -107,13 +106,25 @@ bigger than NUM. * *zip*: automatically compress the output data in gzip format. * *output=OUTSPEC*: instead of writing the profiling data to the output.mlpd file, -do according to *OUTSPEC*: +substitute *%p* in *OUTSPEC* with the current process id and *%t* with the current +date and time, then do according to *OUTSPEC*: * if *OUTSPEC* begins with a *|* character, execute the rest as a program and feed the data to its standard input - * otherwise write the data the the named file + * if *OUTSPEC* begins with a *-* character, use the rest of OUTSPEC as + the filename, but force overwrite any existing file by that name + * otherwise write the data the the named file: note that is a file by that + name already exists, a warning is issued and profiling is disabled. * *report*: the profiling data is sent to mprof-report, which will print a summary -report. This is equivalent to the option: `output=mprof-report -`. +report. This is equivalent to the option: `output=mprof-report -`. If the *output* +option is specified as well, the report will be written to the output file instead of +the console. + +* *port=PORT*: specify the tcp/ip port to use for the listening command server. +Currently not available for windows. +This server is started for example when heapshot=ondemand is used: it will read +commands line by line. The following commands are available: + * *heapshot*: perform a heapshot as soon as possible ## Analyzing the profile data @@ -280,8 +291,9 @@ by setting a low value with the *maxframes* option or by eliminating them completely, by setting it to 0. The other major source of data is the heapshot profiler option: especially -if the managed heap is big, since every object needs to be inspected. The *hsmode* -option can be used to reduce the frequency of the heap shots. +if the managed heap is big, since every object needs to be inspected. The *MODE* +parameter of the *heapshot* option can be used to reduce the frequency of the heap +shots. ### Reduce the timestamp overhead @@ -325,14 +337,14 @@ data, use the *maxframes=0* profiler option. Allocation events can be eliminated with the *noalloc* option. Heap shot data can also be huge: by default it is collected at each major collection. -To reduce the frequency, you can use the *hsmode* profiler option to collect for example +To reduce the frequency, you can specify a heapshot mode: for example to collect every 5 collections (including major and minor): -`hsmode=5gc` +`heapshot=5gc` or when at least 5 seconds passed since the last heap shot: -`hsmode=5000ms` +`heapshot=5000ms` ### Compressing the data diff --git a/mono/profiler/proflog.c b/mono/profiler/proflog.c index 06720a3b915..626435b1f97 100644 --- a/mono/profiler/proflog.c +++ b/mono/profiler/proflog.c @@ -9,11 +9,24 @@ #include #include +#include #include #include #include #include #include +#include +#if defined(HOST_WIN32) || defined(DISABLE_SOCKETS) +#define DISABLE_HELPER_THREAD 1 +#endif + +#ifndef DISABLE_HELPER_THREAD +#include +#include +#include +#include +#endif + #ifdef HOST_WIN32 #include #else @@ -35,6 +48,8 @@ static int do_report = 0; static int do_heap_shot = 0; static int max_call_depth = 100; static int runtime_inited = 0; +static int command_port = 0; +static int heapshot_requested = 0; /* For linux compile with: * gcc -fPIC -shared -o libmono-profiler-log.so proflog.c utils.c -Wall -g -lz `pkg-config --cflags --libs mono-2` @@ -72,7 +87,8 @@ typedef struct _LogBuffer LogBuffer; * [timer overhead: 4 bytes] approximate overhead in nanoseconds of the timer * [flags: 4 bytes] file format flags, should be 0 for now * [pid: 4 bytes] pid of the profiled process - * [sysid: 4 bytes] operating system and architecture identifier + * [port: 2 bytes] tcp port for server if != 0 + * [sysid: 2 bytes] operating system and architecture identifier * * The multiple byte integers are in little-endian format. * @@ -205,7 +221,7 @@ typedef struct _LogBuffer LogBuffer; * * type heap format * type: TYPE_HEAP - * exinfo: one of TYPE_HEAP_START, TYPE_HEAP_END, TYPE_HEAP_OBJECT + * exinfo: one of TYPE_HEAP_START, TYPE_HEAP_END, TYPE_HEAP_OBJECT, TYPE_HEAP_ROOT * if exinfo == TYPE_HEAP_START * [time diff: uleb128] nanoseconds since last timing * if exinfo == TYPE_HEAP_END @@ -215,7 +231,17 @@ typedef struct _LogBuffer LogBuffer; * [class: sleb128] the object MonoClass* as a difference from ptr_base * [size: uleb128] size of the object on the heap * [num_refs: uleb128] number of object references + * if (format version > 1) each referenced objref is preceded by a + * uleb128 encoded offset: the first offset is from the object address + * and each next offset is relative to the previous one * [objrefs: sleb128]+ object referenced as a difference from obj_base + * if exinfo == TYPE_HEAP_ROOT + * [num_roots: uleb128] number of root references + * [num_gc: uleb128] number of major gcs + * [object: sleb128] the object as a difference from obj_base + * [root_type: uleb128] the root_type + * [extra_info: uleb128] the extra_info value + * object, root_type_extra_info are repeated num_roots times * */ struct _LogBuffer { @@ -246,6 +272,12 @@ struct _MonoProfiler { #endif int pipe_output; int last_gc_gen_started; + int command_port; + int server_socket; + int pipes [2]; +#ifndef HOST_WIN32 + pthread_t helper_thread; +#endif }; #ifdef HOST_WIN32 @@ -265,6 +297,15 @@ static __thread LogBuffer* tlsbuffer = NULL; static pthread_key_t tlsbuffer; #endif +static char* +pstrdup (const char *s) +{ + int len = strlen (s) + 1; + char *p = malloc (len); + memcpy (p, s, len); + return p; +} + static LogBuffer* create_buffer (void) { @@ -373,6 +414,17 @@ emit_obj (LogBuffer *logbuffer, void *ptr) assert (logbuffer->data <= logbuffer->data_end); } +static char* +write_int16 (char *buf, int32_t value) +{ + int i; + for (i = 0; i < 2; ++i) { + buf [i] = value; + value >>= 8; + } + return buf + 2; +} + static char* write_int32 (char *buf, int32_t value) { @@ -408,8 +460,9 @@ dump_header (MonoProfiler *profiler) p = write_int64 (p, ((uint64_t)time (NULL)) * 1000); /* startup time */ p = write_int32 (p, get_timer_overhead ()); /* timer overhead */ p = write_int32 (p, 0); /* flags */ - p = write_int32 (p, 0); /* pid */ - p = write_int32 (p, 0); /* opsystem */ + p = write_int32 (p, process_id ()); /* pid */ + p = write_int16 (p, profiler->command_port); /* port */ + p = write_int16 (p, 0); /* opsystem */ #if defined (HAVE_SYS_ZLIB) if (profiler->gzfile) { gzwrite (profiler->gzfile, hbuf, p - hbuf); @@ -449,6 +502,13 @@ dump_buffer (MonoProfiler *profiler, LogBuffer *buf) free_buffer (buf, buf->size); } +static void +process_requests (MonoProfiler *profiler) +{ + if (heapshot_requested) + mono_gc_collect (mono_gc_max_generation ()); +} + static void runtime_initialized (MonoProfiler *profiler) { @@ -471,9 +531,10 @@ safe_dump (MonoProfiler *profiler, LogBuffer *logbuffer) } static int -gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, void *data) +gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, uintptr_t *offsets, void *data) { int i; + uintptr_t last_offset = 0; //const char *name = mono_class_get_name (klass); LogBuffer *logbuffer = ensure_logbuf (20 + num * 8); emit_byte (logbuffer, TYPE_HEAP_OBJECT | TYPE_HEAP); @@ -484,8 +545,11 @@ gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, size &= ~7; emit_value (logbuffer, size); emit_value (logbuffer, num); - for (i = 0; i < num; ++i) + for (i = 0; i < num; ++i) { + emit_value (logbuffer, offsets [i] - last_offset); + last_offset = offsets [i]; emit_obj (logbuffer, refs [i]); + } //if (num) // printf ("obj: %p, klass: %s, refs: %d, size: %d\n", obj, name, (int)num, (int)size); return 0; @@ -493,6 +557,7 @@ gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, static unsigned int hs_mode_ms = 0; static unsigned int hs_mode_gc = 0; +static unsigned int hs_mode_ondemand = 0; static unsigned int gc_count = 0; static uint64_t last_hs_time = 0; @@ -510,11 +575,14 @@ heap_walk (MonoProfiler *profiler) do_walk = 1; else if (hs_mode_gc && (gc_count % hs_mode_gc) == 0) do_walk = 1; + else if (hs_mode_ondemand && heapshot_requested) + do_walk = 1; else if (!hs_mode_ms && !hs_mode_gc && profiler->last_gc_gen_started == mono_gc_max_generation ()) do_walk = 1; if (!do_walk) return; + heapshot_requested = 0; emit_byte (logbuffer, TYPE_HEAP_START | TYPE_HEAP); emit_time (logbuffer, now); mono_gc_walk_heap (0, gc_reference, NULL); @@ -538,7 +606,8 @@ gc_event (MonoProfiler *profiler, MonoGCEvent ev, int generation) { /* to deal with nested gen1 after gen0 started */ if (ev == MONO_GC_EVENT_START) { profiler->last_gc_gen_started = generation; - gc_count++; + if (generation == mono_gc_max_generation ()) + gc_count++; } if (ev == MONO_GC_EVENT_PRE_START_WORLD) heap_walk (profiler); @@ -635,6 +704,7 @@ gc_alloc (MonoProfiler *prof, MonoObject *obj, MonoClass *klass) EXIT_LOG (logbuffer); if (logbuffer->next) safe_dump (prof, logbuffer); + process_requests (prof); //printf ("gc alloc %s at %p\n", mono_class_get_name (klass), obj); } @@ -655,6 +725,23 @@ gc_moves (MonoProfiler *prof, void **objects, int num) EXIT_LOG (logbuffer); } +static void +gc_roots (MonoProfiler *prof, int num, void **objects, int *root_types, uintptr_t *extra_info) +{ + int i; + LogBuffer *logbuffer = ensure_logbuf (5 + num * 18); + ENTER_LOG (logbuffer, "gcroots"); + emit_byte (logbuffer, TYPE_HEAP_ROOT | TYPE_HEAP); + emit_value (logbuffer, num); + emit_value (logbuffer, mono_gc_collection_count (mono_gc_max_generation ())); + for (i = 0; i < num; ++i) { + emit_obj (logbuffer, objects [i]); + emit_value (logbuffer, root_types [i]); + emit_value (logbuffer, extra_info [i]); + } + EXIT_LOG (logbuffer); +} + static void gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj) { @@ -674,6 +761,7 @@ gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *o if (op == MONO_PROFILER_GC_HANDLE_CREATED) emit_obj (logbuffer, obj); EXIT_LOG (logbuffer); + process_requests (prof); } static char* @@ -737,6 +825,7 @@ image_loaded (MonoProfiler *prof, MonoImage *image, int result) EXIT_LOG (logbuffer); if (logbuffer->next) safe_dump (prof, logbuffer); + process_requests (prof); } static void @@ -774,6 +863,7 @@ class_loaded (MonoProfiler *prof, MonoClass *klass, int result) EXIT_LOG (logbuffer); if (logbuffer->next) safe_dump (prof, logbuffer); + process_requests (prof); } static void @@ -789,6 +879,7 @@ method_enter (MonoProfiler *prof, MonoMethod *method) emit_time (logbuffer, now); emit_method (logbuffer, method); EXIT_LOG (logbuffer); + process_requests (prof); } static void @@ -806,6 +897,7 @@ method_leave (MonoProfiler *prof, MonoMethod *method) EXIT_LOG (logbuffer); if (logbuffer->next) safe_dump (prof, logbuffer); + process_requests (prof); } static void @@ -824,6 +916,7 @@ method_exc_leave (MonoProfiler *prof, MonoMethod *method) emit_time (logbuffer, now); emit_method (logbuffer, method); EXIT_LOG (logbuffer); + process_requests (prof); } static void @@ -851,6 +944,7 @@ method_jitted (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int r EXIT_LOG (logbuffer); if (logbuffer->next) safe_dump (prof, logbuffer); + process_requests (prof); } static void @@ -871,6 +965,7 @@ throw_exc (MonoProfiler *prof, MonoObject *object) if (do_bt) emit_bt (logbuffer, &data); EXIT_LOG (logbuffer); + process_requests (prof); } static void @@ -906,6 +1001,7 @@ monitor_event (MonoProfiler *profiler, MonoObject *object, MonoProfilerMonitorEv if (do_bt) emit_bt (logbuffer, &data); EXIT_LOG (logbuffer); + process_requests (profiler); } static void @@ -947,6 +1043,14 @@ thread_name (MonoProfiler *prof, uintptr_t tid, const char *name) static void log_shutdown (MonoProfiler *prof) { +#ifndef DISABLE_HELPER_THREAD + if (prof->command_port) { + char c = 1; + void *res; + write (prof->pipes [1], &c, 1); + pthread_join (prof->helper_thread, &res); + } +#endif take_lock (); if (TLS_GET (tlsbuffer)) dump_buffer (prof, TLS_GET (tlsbuffer)); @@ -963,30 +1067,239 @@ log_shutdown (MonoProfiler *prof) free (prof); } +static char* +new_filename (const char* filename) +{ + time_t t = time (NULL); + int pid = process_id (); + char pid_buf [16]; + char time_buf [16]; + char *res, *d; + const char *p; + int count_dates = 0; + int count_pids = 0; + int s_date, s_pid; + struct tm *ts; + for (p = filename; *p; p++) { + if (*p != '%') + continue; + p++; + if (*p == 't') + count_dates++; + else if (*p == 'p') + count_pids++; + else if (*p == 0) + break; + } + if (!count_dates && !count_pids) + return pstrdup (filename); + snprintf (pid_buf, sizeof (pid_buf), "%d", pid); + ts = gmtime (&t); + snprintf (time_buf, sizeof (time_buf), "%d%02d%02d%02d%02d%02d", + 1900 + ts->tm_year, 1 + ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); + s_date = strlen (time_buf); + s_pid = strlen (pid_buf); + d = res = malloc (strlen (filename) + s_date * count_dates + s_pid * count_pids); + for (p = filename; *p; p++) { + if (*p != '%') { + *d++ = *p; + continue; + } + p++; + if (*p == 't') { + strcpy (d, time_buf); + d += s_date; + continue; + } else if (*p == 'p') { + strcpy (d, pid_buf); + d += s_pid; + continue; + } else if (*p == '%') { + *d++ = '%'; + continue; + } else if (*p == 0) + break; + *d++ = '%'; + *d++ = *p; + } + *d = 0; + return res; +} + +#ifndef DISABLE_HELPER_THREAD +static void* +helper_thread (void* arg) +{ + MonoProfiler* prof = arg; + int command_socket; + int len; + char buf [64]; + MonoThread *thread = NULL; + + //fprintf (stderr, "Server listening\n"); + command_socket = -1; + while (1) { + fd_set rfds; + struct timeval tv; + int max_fd = -1; + FD_ZERO (&rfds); + FD_SET (prof->server_socket, &rfds); + max_fd = prof->server_socket; + FD_SET (prof->pipes [0], &rfds); + if (max_fd < prof->pipes [0]) + max_fd = prof->pipes [0]; + if (command_socket >= 0) { + FD_SET (command_socket, &rfds); + if (max_fd < command_socket) + max_fd = command_socket; + } + tv.tv_sec = 1; + tv.tv_usec = 0; + len = select (max_fd + 1, &rfds, NULL, NULL, &tv); + if (FD_ISSET (prof->pipes [0], &rfds)) { + /* time to shut down */ + if (thread) + mono_thread_detach (thread); + /*fprintf (stderr, "helper shutdown\n");*/ + return NULL; + } + if (runtime_inited && !thread) { + thread = mono_thread_attach (mono_get_root_domain ()); + /*fprintf (stderr, "attached\n");*/ + } + if (command_socket >= 0 && FD_ISSET (command_socket, &rfds)) { + len = read (command_socket, buf, sizeof (buf) - 1); + if (len < 0) + continue; + if (len == 0) { + close (command_socket); + command_socket = -1; + continue; + } + buf [len] = 0; + if (strcmp (buf, "heapshot\n") == 0) { + heapshot_requested = 1; + //fprintf (stderr, "perform heapshot\n"); + if (thread) + process_requests (prof); + } + continue; + } + if (!FD_ISSET (prof->server_socket, &rfds)) { + continue; + } + command_socket = accept (prof->server_socket, NULL, NULL); + if (command_socket < 0) + continue; + //fprintf (stderr, "Accepted connection\n"); + } + return NULL; +} + +static int +start_helper_thread (MonoProfiler* prof) +{ + struct sockaddr_in server_address; + int r; + socklen_t slen; + if (pipe (prof->pipes) < 0) { + fprintf (stderr, "Cannot create pipe\n"); + return 0; + } + prof->server_socket = socket (PF_INET, SOCK_STREAM, 0); + if (prof->server_socket < 0) { + fprintf (stderr, "Cannot create server socket\n"); + return 0; + } + memset (&server_address, 0, sizeof (server_address)); + server_address.sin_family = AF_INET; + server_address.sin_addr.s_addr = INADDR_ANY; + server_address.sin_port = htons (prof->command_port); + if (bind (prof->server_socket, (struct sockaddr *) &server_address, sizeof (server_address)) < 0) { + fprintf (stderr, "Cannot bind server socket, port: %d: %s\n", prof->command_port, strerror (errno)); + close (prof->server_socket); + return 0; + } + if (listen (prof->server_socket, 1) < 0) { + fprintf (stderr, "Cannot listen server socket\n"); + close (prof->server_socket); + return 0; + } + if (getsockname (prof->server_socket, (struct sockaddr *)&server_address, &slen) == 0) { + prof->command_port = ntohs (server_address.sin_port); + /*fprintf (stderr, "Assigned server port: %d\n", prof->command_port);*/ + } + + r = pthread_create (&prof->helper_thread, NULL, helper_thread, prof); + if (r) { + close (prof->server_socket); + return 0; + } + return 1; +} +#endif + static MonoProfiler* create_profiler (const char *filename) { MonoProfiler *prof; + char *nf; + int force_delete = 0; prof = calloc (1, sizeof (MonoProfiler)); - if (do_report) /* FIXME: use filename as output */ - filename = "|mprof-report -"; - if (!filename) - filename = "output.mlpd"; - if (*filename == '|') { - prof->file = popen (filename + 1, "w"); + prof->command_port = command_port; + if (filename && *filename == '-') { + force_delete = 1; + filename++; + } + if (!filename) { + if (do_report) + filename = "|mprof-report -"; + else + filename = "output.mlpd"; + nf = filename; + } else { + nf = new_filename (filename); + if (do_report) { + int s = strlen (nf) + 32; + char *p = malloc (s); + snprintf (p, s, "|mprof-report '--out=%s' -", nf); + free (nf); + nf = p; + } + } + if (*nf == '|') { + prof->file = popen (nf + 1, "w"); prof->pipe_output = 1; } else { - unlink (filename); - prof->file = fopen (filename, "wb"); + FILE *f; + if (force_delete) + unlink (nf); + if ((f = fopen (nf, "r"))) { + fclose (f); + fprintf (stderr, "The Mono profiler won't overwrite existing filename: %s.\n", nf); + fprintf (stderr, "Profiling disabled: use a different name or -FILENAME to force overwrite.\n"); + free (prof); + return NULL; + } + prof->file = fopen (nf, "wb"); } if (!prof->file) { - printf ("Cannot create profiler output: %s\n", filename); + fprintf (stderr, "Cannot create profiler output: %s\n", nf); exit (1); } #if defined (HAVE_SYS_ZLIB) if (use_zip) prof->gzfile = gzdopen (fileno (prof->file), "wb"); +#endif +#ifndef DISABLE_HELPER_THREAD + if (hs_mode_ondemand) { + if (!start_helper_thread (prof)) + prof->command_port = 0; + } +#else + if (hs_mode_ondemand) + fprintf (stderr, "Ondemand heapshot unavailable on this arch.\n"); #endif dump_header (prof); return prof; @@ -1001,15 +1314,17 @@ usage (int do_exit) printf ("\thelp show this usage info\n"); printf ("\t[no]alloc enable/disable recording allocation info\n"); printf ("\t[no]calls enable/disable recording enter/leave method events\n"); - printf ("\theapshot record heap shot info (by default at each major collection)\n"); - printf ("\thsmode=MODE heapshot mode: every XXms milliseconds or every YYgc collections\n"); + printf ("\theapshot[=MODE] record heap shot info (by default at each major collection)\n"); + printf ("\t MODE: every XXms milliseconds, every YYgc collections, ondemand\n"); printf ("\ttime=fast use a faster (but more inaccurate) timer\n"); printf ("\tmaxframes=NUM collect up to NUM stack frames\n"); printf ("\tcalldepth=NUM ignore method events for call chain depth bigger than NUM\n"); - printf ("\toutput=FILENAME write the data to file FILENAME\n"); + printf ("\toutput=FILENAME write the data to file FILENAME (-FILENAME to overwrite)\n"); printf ("\toutput=|PROGRAM write the data to the stdin of PROGRAM\n"); + printf ("\t %%t is subtituted with date and time, %%p with the pid\n"); printf ("\treport create a report instead of writing the raw data to a file\n"); printf ("\tzip compress the output data\n"); + printf ("\tport=PORTNUM use PORTNUM for the listening command server\n"); if (do_exit) exit (1); } @@ -1036,6 +1351,10 @@ match_option (const char* p, const char *opt, char **rval) *rval = val; return opt + l; } + if (p [len] == 0 || p [len] == ',') { + *rval = NULL; + return p + len + (p [len] == ','); + } usage (1); } else { if (p [len] == 0) @@ -1047,6 +1366,30 @@ match_option (const char* p, const char *opt, char **rval) return p; } +static void +set_hsmode (char* val, int allow_empty) +{ + char *end; + unsigned int count; + if (allow_empty && !val) + return; + if (strcmp (val, "ondemand") == 0) { + hs_mode_ondemand = 1; + free (val); + return; + } + count = strtoul (val, &end, 10); + if (val == end) + usage (1); + if (strcmp (end, "ms") == 0) + hs_mode_ms = count; + else if (strcmp (end, "gc") == 0) + hs_mode_gc = count; + else + usage (1); + free (val); +} + /* * declaration to silence the compiler: this is the entry point that * mono will load from the shared library and call. @@ -1116,25 +1459,17 @@ mono_profiler_startup (const char *desc) do_report = 1; continue; } - if ((opt = match_option (p, "heapshot", NULL)) != p) { + if ((opt = match_option (p, "heapshot", &val)) != p) { events &= ~MONO_PROFILE_ALLOCATIONS; events &= ~MONO_PROFILE_ENTER_LEAVE; nocalls = 1; do_heap_shot = 1; + set_hsmode (val, 1); continue; } if ((opt = match_option (p, "hsmode", &val)) != p) { - char *end; - unsigned int count = strtoul (val, &end, 10); - if (val == end) - usage (1); - if (strcmp (end, "ms") == 0) - hs_mode_ms = count; - else if (strcmp (end, "gc") == 0) - hs_mode_gc = count; - else - usage (1); - free (val); + fprintf (stderr, "The hsmode profiler option is obsolete, use heapshot=MODE.\n"); + set_hsmode (val, 0); continue; } if ((opt = match_option (p, "zip", NULL)) != p) { @@ -1145,6 +1480,12 @@ mono_profiler_startup (const char *desc) filename = val; continue; } + if ((opt = match_option (p, "port", &val)) != p) { + char *end; + command_port = strtoul (val, &end, 10); + free (val); + continue; + } if ((opt = match_option (p, "maxframes", &val)) != p) { char *end; num_frames = strtoul (val, &end, 10); @@ -1174,13 +1515,15 @@ mono_profiler_startup (const char *desc) utils_init (fast_time); prof = create_profiler (filename); + if (!prof) + return; init_thread (); mono_profiler_install (prof, log_shutdown); mono_profiler_install_gc (gc_event, gc_resize); mono_profiler_install_allocation (gc_alloc); mono_profiler_install_gc_moves (gc_moves); - mono_profiler_install_gc_roots (gc_handle); + mono_profiler_install_gc_roots (gc_handle, gc_roots); mono_profiler_install_class (NULL, class_loaded, NULL, NULL); mono_profiler_install_module (NULL, image_loaded, NULL, NULL); mono_profiler_install_thread (thread_start, thread_end); diff --git a/mono/profiler/proflog.h b/mono/profiler/proflog.h index 5aaf6a4ce5a..5011eab9a44 100644 --- a/mono/profiler/proflog.h +++ b/mono/profiler/proflog.h @@ -5,7 +5,11 @@ #define LOG_HEADER_ID 0x4D505A01 #define LOG_VERSION_MAJOR 0 #define LOG_VERSION_MINOR 2 -#define LOG_DATA_VERSION 1 +#define LOG_DATA_VERSION 3 +/* + * version 2: added offsets in heap walk + * version 3: added GC roots + */ enum { TYPE_ALLOC, @@ -20,6 +24,7 @@ enum { TYPE_HEAP_START = 0 << 4, TYPE_HEAP_END = 1 << 4, TYPE_HEAP_OBJECT = 2 << 4, + TYPE_HEAP_ROOT = 3 << 4, /* extended type for TYPE_METADATA */ TYPE_START_LOAD = 1 << 4, TYPE_END_LOAD = 2 << 4, diff --git a/mono/profiler/utils.c b/mono/profiler/utils.c index b16e9bfc6aa..8bf57a72f7c 100644 --- a/mono/profiler/utils.c +++ b/mono/profiler/utils.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef HOST_WIN32 #include #else @@ -412,3 +413,13 @@ thread_id (void) #endif } +uintptr_t +process_id (void) +{ +#ifdef HOST_WIN32 + return 0; /* FIXME */ +#else + return (uintptr_t)getpid (); +#endif +} + diff --git a/mono/profiler/utils.h b/mono/profiler/utils.h index fd104ad4fca..3af56d202c6 100644 --- a/mono/profiler/utils.h +++ b/mono/profiler/utils.h @@ -12,6 +12,7 @@ void free_buffer (void *buf, int size); void take_lock (void); void release_lock (void); uintptr_t thread_id (void); +uintptr_t process_id (void); void encode_uleb128 (uint64_t value, uint8_t *buf, uint8_t **endbuf); void encode_sleb128 (intptr_t value, uint8_t *buf, uint8_t **endbuf); diff --git a/mono/tests/gc-oom-handling.cs b/mono/tests/gc-oom-handling.cs index dc7c7f95c76..3d22294f7d0 100644 --- a/mono/tests/gc-oom-handling.cs +++ b/mono/tests/gc-oom-handling.cs @@ -4,19 +4,23 @@ using System.Collections.Generic; class Driver { static int Main () { Console.WriteLine ("start"); - var l = new List (); + var l = new object[40000]; try { for (int i = 0; i < 40000; ++i) { var foo = new byte[2000]; - //Console.WriteLine ("done {0}",i); - if (foo == null) - Console.WriteLine ("WTF"); - l.Add (foo); + l[i] = foo; } Console.WriteLine ("done"); - return -1; + return 1; } catch (Exception e) { - l.Clear (); + /*Create massive fragmentation - hopefully*/ + for (int i = 0; i < 40000; i += 2) + l[i] = null; + /*Fist major schedule the given block range for evacuation*/ + GC.Collect (); + /*Second major triggers evacuation*/ + GC.Collect (); + Array.Clear (l, 0, 40000); l = null; Console.WriteLine ("OOM done"); } diff --git a/mono/tests/gc-oom-handling2.cs b/mono/tests/gc-oom-handling2.cs index 0a38190e820..e048113fb05 100644 --- a/mono/tests/gc-oom-handling2.cs +++ b/mono/tests/gc-oom-handling2.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; +using System.Reflection; + class Driver { + /*Test that GC handles interning failure correctly*/ static void DumpStuff () { Console.WriteLine ("CWL under OOM - should not print {0}", 99); Console.WriteLine ("CWL under OOM - should not print {0}{1}", 22, 44.4); @@ -9,6 +12,8 @@ class Driver { static int Main () { Console.WriteLine ("start"); + Assembly corlib = typeof (object).Assembly; + Module module = corlib.GetModules ()[0]; var r = new Random (123456); var l = new List (); try { @@ -17,11 +22,23 @@ class Driver { l.Add (foo); } Console.WriteLine ("done"); - return -1; + return 1; } catch (Exception) { try { DumpStuff (); + return 2; + } catch (Exception) {} + + try { + module.GetTypes (); + return 3; + } catch (Exception) {} + + try { + corlib.GetTypes (); + return 4; } catch (Exception) {} + l.Clear (); l = null; diff --git a/mono/utils/CMakeLists.txt b/mono/utils/CMakeLists.txt deleted file mode 100644 index 379b047b034..00000000000 --- a/mono/utils/CMakeLists.txt +++ /dev/null @@ -1,90 +0,0 @@ -###noinst_LTLIBRARIES = libmonoutils.la - -###INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mono $(LIBGC_CFLAGS) $(GLIB_CFLAGS) - -###if ENABLE_DTRACE - -###BUILT_SOURCES = mono-dtrace.h - -###mono-dtrace.h: $(top_srcdir)/data/mono.d -### $(DTRACE) $(DTRACEFLAGS) -h -s $(top_srcdir)/data/mono.d -o $@ || > $@ -### -###endif - -if(EGLIB_BUILD) - set(hash_sources mono-ehash.c) -else() - set(hash_sources mono-hash.c) -endif() - -set(libmonoutils_la_SOURCES - ${hash_sources} - mono-md5.c - mono-sha1.c - mono-logger.c - mono-codeman.c - dlmalloc.h - dlmalloc.c - mono-counters.c - mono-compiler.h - mono-dl.c - mono-dl.h - mono-internal-hash.c - mono-internal-hash.h - mono-io-portability.c - mono-io-portability.h - monobitset.c - mono-filemap.c - mono-math.c - mono-mmap.c - mono-mmap.h - mono-proclib.c - mono-proclib.h - mono-string.h - mono-time.c - mono-time.h - strtod.h - strtod.c - strenc.h - strenc.c - mono-uri.c - mono-poll.c - mono-path.c - mono-semaphore.h - mono-sigcontext.h - mono-stdlib.c - mono-property-hash.h - mono-property-hash.c - mono-value-hash.h - mono-value-hash.c - freebsd-elf_common.h - freebsd-elf32.h - freebsd-elf64.h - freebsd-dwarf.h - dtrace.h - gc_wrapper.h) - -set(libmonoutilsincludedir ${includedir}/mono-${API_VER}/mono/utils) - -set(libmonoutilsinclude_HEADERS - monobitset.h - mono-codeman.h - mono-counters.h - mono-digest.h - mono-embed.h - mono-logger.h - mono-hash.h - mono-math.h - mono-membar.h - mono-path.h - mono-poll.h - mono-uri.h - mono-stdlib.h) - -set(EXTRA_DIST ChangeLog mono-hash.c mono-hash.h mono-ehash.c) - -set(top_srcdir ../../) -INCLUDE_DIRECTORIES(${top_srcdir} ${top_srcdir}/mono ${GLIB2_INCLUDE_DIRS}) -ADD_DEFINITIONS(${CFLAGS} ${LIBGC_CFLAGS} ${CPPFLAGS}) -ADD_LIBRARY(monoutils-static STATIC ${libmonoutils_la_SOURCES}) -ADD_LIBRARY(monoutils SHARED ${libmonoutils_la_SOURCES}) \ No newline at end of file diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt deleted file mode 100644 index bdfc8f60ffa..00000000000 --- a/scripts/CMakeLists.txt +++ /dev/null @@ -1,230 +0,0 @@ -# -# Scripts that we install -# -# Starting with Mono 2.0, the majority of the tools default to the -# 2.0 profile. Commands that support the 1.0 toolchain and must -# run under 1.0 have the number 1 appended to their command names -# (for example mcs1 is the C# 1.0 compiler) and are listed in the -# scripts_1_0 compat variable. -# -# To preserve compatibility with old Makefiles and tools we keep the -# command names that had the suffix 2 (like wsdl2) -# -if(USE_BATCH_FILES) -message(FATAL_ERROR FIXME) -set(SCRIPT_IN script.bat.in) -set(FILTER sed -e 's,\.bat\.exe,\.exe,g' -e 's,/,\\,g') -set(SCRIPT_SUFFIX .bat) -else() -set(SCRIPT_IN script.in) -set(FILTER cat) -set(SCRIPT_SUFFIX) -endif() - -set(COMPAT_1_0_SUFFIX 1${SCRIPT_SUFFIX}) -set(COMPAT_2_0_SUFFIX 2${SCRIPT_SUFFIX}) - -set(scripts_1_0_compat - al1${SCRIPT_SUFFIX} - genxs1${SCRIPT_SUFFIX} - ilasm1${SCRIPT_SUFFIX} - mcs1${SCRIPT_SUFFIX} - mkbundle1${SCRIPT_SUFFIX} - gacutil1${SCRIPT_SUFFIX} - monop1${SCRIPT_SUFFIX} - resgen1${SCRIPT_SUFFIX} - wsdl1${SCRIPT_SUFFIX}) - -set(scripts_1_0 - caspol${SCRIPT_SUFFIX} - cert2spc${SCRIPT_SUFFIX} - certmgr${SCRIPT_SUFFIX} - chktrust${SCRIPT_SUFFIX} - cilc${SCRIPT_SUFFIX} - disco${SCRIPT_SUFFIX} - dtd2xsd${SCRIPT_SUFFIX} - dtd2rng${SCRIPT_SUFFIX} - installvst${SCRIPT_SUFFIX} - genxs${SCRIPT_SUFFIX} - macpack${SCRIPT_SUFFIX} - mcs${SCRIPT_SUFFIX} - mjs${SCRIPT_SUFFIX} - monolinker${SCRIPT_SUFFIX} - mono-cil-strip${SCRIPT_SUFFIX} - mozroots${SCRIPT_SUFFIX} - permview${SCRIPT_SUFFIX} - prj2make${SCRIPT_SUFFIX} - secutil${SCRIPT_SUFFIX} - setreg${SCRIPT_SUFFIX} - signcode${SCRIPT_SUFFIX} - soapsuds${SCRIPT_SUFFIX} - xsd${SCRIPT_SUFFIX}) - -set(scripts_1_0_umask - makecert${SCRIPT_SUFFIX} - sn${SCRIPT_SUFFIX}) - -set(scripts_2_0 - al2${SCRIPT_SUFFIX} - csharp${SCRIPT_SUFFIX} - gacutil2${SCRIPT_SUFFIX} - gmcs${SCRIPT_SUFFIX} - httpcfg${SCRIPT_SUFFIX} - ilasm2${SCRIPT_SUFFIX} - mconfig${SCRIPT_SUFFIX} - mkbundle2${SCRIPT_SUFFIX} - mdoc${SCRIPT_SUFFIX} - mono-api-info${SCRIPT_SUFFIX} - mono-shlib-cop${SCRIPT_SUFFIX} - monop2${SCRIPT_SUFFIX} - resgen2${SCRIPT_SUFFIX} - pdb2mdb${SCRIPT_SUFFIX} - wsdl2${SCRIPT_SUFFIX} - xsd2${SCRIPT_SUFFIX} - mono-xmltool${SCRIPT_SUFFIX} - sgen${SCRIPT_SUFFIX} - sqlmetal${SCRIPT_SUFFIX} - sqlsharp${SCRIPT_SUFFIX} - svcutil${SCRIPT_SUFFIX} - xbuild${SCRIPT_SUFFIX}) - -set(MDOC_SUBCOMMANDS - mdoc-assemble - mdoc-export-html - mdoc-export-msxdoc - mdoc-update - mdoc-validate) - -set(MDOC_COMPAT - mdassembler - mdvalidater - monodocer - monodocs2html - monodocs2slashdoc) - -set(bin_SCRIPTS - ${scripts_1_0} - ${scripts_1_0_umask} - ${scripts_1_0_compat} - ${scripts_defaults} - ${scripts_2_0} - ${scripts_service} - ${scripts_nunit} - ${scripts_rpmhelpers} - ${MDOC_SUBCOMMANDS} - ${MDOC_COMPAT} - mod - mono-test-install) - -# -# these are the new defaults, 2.0 profile-based commands -# -# we can move scripts_1_0 scripts here as we see fit, if(we need to -# keep a 1.0 command available, we should additionally put it on -# the scripts_1_0_compat list -# -set(scripts_defaults - al${SCRIPT_SUFFIX} - ilasm${SCRIPT_SUFFIX} - gacutil${SCRIPT_SUFFIX} - mkbundle${SCRIPT_SUFFIX} - monop${SCRIPT_SUFFIX} - resgen${SCRIPT_SUFFIX} - wsdl${SCRIPT_SUFFIX}) - -###scripts_service = mono-service mono-service2 -###scripts_nunit = nunit-console${SCRIPT_SUFFIX} nunit-console2${SCRIPT_SUFFIX} -###scripts_rpmhelpers = mono-find-provides mono-find-requires -### -###CLEANFILES = ${scripts_1_0} ${scripts_1_0_umask} ${scripts_2_0} ${scripts_defaults} ${scripts_1_0_compat} mono-service mono-service2 nunit-console nunit-console2 mono-find-provides mono-find-requires mod ${MDOC_SUBCOMMANDS} -###DISTCLEANFILES = ${pkgconfig_DATA} ${scripts_rpmhelpers} -### -###EXTRA_DIST = \ -### script.in \ -### script.bat.in \ -### script_umask.in \ -### script_umask.bat.in \ -### mod.in \ -### mono-service.in \ -### mono-find-provides.in \ -### mono-find-requires.in \ -### mono-test-install \ -### ${MDOC_COMPAT} \ -### patch-quiet.sh -### -if(USE_JIT) -set(mono_interp mono) -else() -set(mono_interp mint) -endif() - -if(PLATFORM_WIN32) -if(CROSS_COMPILING) -set(plat_bindir ${bindir}) -set(mono_instdir ${prefix}/lib/mono) -else() -set(plat_bindir ${shell cygpath -m ${libdir}}) -set(mono_instdir ${shell cygpath -m ${libdir}}/mono) -endif() -else() -set(plat_bindir ${bindir}) -set(mono_instdir ${prefix}/lib/mono) -endif() - -function(rewrite input output exe version) - file(READ ${input} s) - string(REPLACE "\@bindir\@" "${bindir_full}" s ${s}) - string(REPLACE "\@mono_instdir\@" "${mono_instdir}" s ${s}) - string(REPLACE "\@mono_interp\@" "${mono_interp}" s ${s}) - string(REPLACE "\@framework_version\@" "${version}" s ${s}) - string(REPLACE "\@exe_name\@" "${exe}" s ${s}) - file(WRITE ${output} ${s}) -endfunction() - -function(rewrite_debug input output exe version) - file(READ ${input} s) - string(REPLACE "\@bindir\@" "${bindir_full}" s ${s}) - string(REPLACE "\@mono_instdir\@" "${mono_instdir}" s ${s}) - string(REPLACE "\@mono_interp\@" "${mono_interp} --debug" s ${s}) - string(REPLACE "\@framework_version\@" "${version}" s ${s}) - string(REPLACE "\@exe_name\@" "${exe}" s ${s}) - file(WRITE ${output} ${s}) -endfunction() - -set(srcdir ${top_srcdir}/scripts) - -# FIXME: Make these into targets -rewrite(mono-service.in mono-service mono-service 1.0) -rewrite(mono-service.in mono-service2 mono-service2 2.0) -rewrite_debug(${SCRIPT_IN} nunit-console${SCRIPT_SUFFIX} nunit-console 1.0) -rewrite_debug(${SCRIPT_IN} nunit-console2${SCRIPT_SUFFIX} nunit-console 2.0) -rewrite(mod.in mod${SCRIPT_SUFFIX} mod 1.0) - -foreach(script ${scripts_1_0}) - rewrite(${srcdir}/script.in ${script} ${script} 1.0) -endforeach() - -foreach(script ${scripts_1_0_umask}) - rewrite(${srcdir}/script_umask.in ${script} ${script} 1.0) -endforeach() - -foreach(script ${scripts_1_0_compat}) - string(REPLACE ${COMPAT_1_0_SUFFIX} "" exe ${script}) - rewrite(${srcdir}/script_umask.in ${script} ${exe} 1.0) -endforeach() - -foreach(script ${scripts_defaults}) - rewrite(${srcdir}/script.in ${script} ${script} 2.0) -endforeach() - -foreach(script ${scripts_2_0}) - string(REPLACE ${COMPAT_2_0_SUFFIX} "" exe ${script}) - rewrite(${srcdir}/script.in ${script} ${exe} 2.0) -endforeach() - -foreach(script ${MDOC_SUBCOMMANDS}) - string(REPLACE "mdoc-" "" cmd ${script}) - file(WRITE ${script} "#!/bin/sh\nexec mdoc ${cmd} \"$@\"\n") -endforeach() - -install(PROGRAMS ${bin_SCRIPTS} DESTINATION bin) diff --git a/support/CMakeLists.txt b/support/CMakeLists.txt deleted file mode 100644 index d834487243c..00000000000 --- a/support/CMakeLists.txt +++ /dev/null @@ -1,162 +0,0 @@ - -# Source code which helps implement the ANSI C standards, and thus *should* be -# portable to any platform having a C compiler. -set(MPH_C_SOURCE - errno.c - map.c - map.h - mph.h - signal.c - stdio.c - string.c - stdlib.c) - -# Source code which helps implement POSIX and other related Unix standards, -# and *may* be portable between Unix platforms. -set(MPH_UNIX_SOURCE - dirent.c - fcntl.c - fstab.c - grp.c - macros.c - old-map.c - old-map.h - pwd.c - serial.c - sys-mman.c - sys-sendfile.c - sys-stat.c - sys-statvfs.c - sys-time.c - sys-utsname.c - sys-wait.c - sys-xattr.c - syslog.c - time.c - unistd.c - utime.c - x-struct-str.c) - -if(PLATFORM_WIN32) -set(MPH_SOURCE ${MPH_C_SOURCE}) -set(MPH_LIBS ${GLIB_LIBS}) -else() -set(MPH_SOURCE ${MPH_C_SOURCE} ${MPH_UNIX_SOURCE}) -set(MPH_LIBS ${GLIB_LIBS}) -endif() - -set(MINIZIP_SOURCE - minizip/crypt.h - minizip/ioapi.c - minizip/ioapi.h - minizip/unzip.c - minizip/unzip.h - minizip/zip.c - minizip/zip.h) - -set(ZLIB_SOURCES - adler32.c - compress.c - crc32.c - gzio.c - uncompr.c - deflate.c - trees.c - zutil.c - inflate.c - infback.c - inftrees.c - inffast.c - crc32.h - deflate.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zconf.h - zlib.h - zutil.h) - -if(HAVE_ZLIB) -set(Z_SOURCE zlib-helper.c) -set(Z_LIBS -lz) -else() -set(Z_SOURCE zlib-helper.c ${ZLIB_SOURCES}) -set(Z_LIBS) -endif() - -set(libMonoPosixHelper_la_SOURCES - ${MPH_SOURCE} - ${Z_SOURCE} - ${MINIZIP_SOURCE}) - -set(libMonoPosixHelper_la_LIBADD - ${MPH_LIBS} - ${Z_LIBS} - ${XATTR_LIB}) - -# set(libMonoPosixHelper_la_LDFLAGS -no-undefined -version-info 1:0:1 -###set(libMonoPosixHelper_la_LDFLAGS -no-undefined -avoid-version) -###set(libMonoSupportW_la_LDFLAGS -no-undefined -avoid-version) - -set(libMonoSupportW_la_SOURCES - supportw.c - support-heap.c - supportw.h) - -set(libMonoSupportW_la_LIBADD - ${GLIB_LIBS}) - -include_directories(${top_srcdir}) -include_directories(${GLIB2_INCLUDE_DIRS}) -set(CMAKE_C_FLAGS "${CFLAGS} ${CPPFLAGS}") -link_directories(../mini) - -add_library(MonoPosixHelper SHARED ${libMonoPosixHelper_la_SOURCES}) -target_link_libraries(MonoPosixHelper ${libMonoPosixHelper_la_LIBADD}) - -if(PLATFORM_WIN32) -else() -###set(lib_LTLIBRARIES -### libMonoPosixHelper.la -### ${SUPPORT}) -endif() - -# -# Use this target to refresh the values in map.[ch] -# -add_custom_target(refresh - COMMAND cp `pkg-config --variable=Programs create-native-map` . - COMMAND ${top_builddir}/runtime/mono-wrapper create-native-map.exe - --autoconf-member=d_off - --autoconf-member=d_reclen - --autoconf-member=d_type - --exclude-native-symbol=Mono_Posix_Stdlib_snprintf - --impl-macro=_GNU_SOURCE --impl-macro=_XOPEN_SOURCE - --impl-header="" - --impl-header="" - --autoconf-header="" - --autoconf-header="" - --autoconf-header="" - --autoconf-header="" - --autoconf-header="" - --autoconf-header="" - --autoconf-header="" - --impl-header="" - --impl-header="" - --autoconf-header="" - --autoconf-header="" - --impl-header="" - --autoconf-header="" - --autoconf-header="" - --autoconf-header="" - --impl-header="" - --impl-header=""mph.h"" - --rename-member=st_atime=st_atime_ - --rename-member=st_ctime=st_ctime_ - --rename-member=st_mtime=st_mtime_ - --rename-namespace=Mono.Unix.Native=Mono.Posix - --library=MonoPosixHelper - ${mcs_topdir}/class/lib/net_2_0/Mono.Posix.dll map -) \ No newline at end of file