Обновлен mono до 4.2.1

This commit is contained in:
Kernell 2015-11-28 04:33:40 +03:00
parent 70739e190e
commit 821c453132
274 changed files with 25022 additions and 39477 deletions

View File

@ -1029,6 +1029,7 @@ typedef union {
#define amd64_sse_andpd_reg_membase(inst,dreg,basereg,disp) emit_sse_reg_membase ((inst),(dreg),(basereg), (disp), 0x66, 0x0f, 0x54)
#define amd64_sse_movsd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf2, 0x0f, 0x10)
#define amd64_sse_movss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x10)
#define amd64_sse_movsd_reg_membase(inst,dreg,basereg,disp) emit_sse_reg_membase ((inst), (dreg), (basereg), (disp), 0xf2, 0x0f, 0x10)
@ -1039,14 +1040,17 @@ typedef union {
#define amd64_sse_movss_reg_membase(inst,dreg,basereg,disp) emit_sse_reg_membase ((inst), (dreg), (basereg), (disp), 0xf3, 0x0f, 0x10)
#define amd64_sse_comisd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst),(dreg),(reg),0x66,0x0f,0x2f)
#define amd64_sse_comiss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst),(dreg),(reg),0x67,0x0f,0x2f)
#define amd64_sse_comisd_reg_membase(inst,dreg,basereg,disp) emit_sse_reg_membase ((inst), (dreg), (basereg), (disp), 0x66, 0x0f, 0x2f)
#define amd64_sse_ucomisd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst),(dreg),(reg),0x66,0x0f,0x2e)
#define amd64_sse_cvtsd2si_reg_reg(inst,dreg,reg) emit_sse_reg_reg_size ((inst), (dreg), (reg), 0xf2, 0x0f, 0x2d, 8)
#define amd64_sse_cvtss2si_reg_reg(inst,dreg,reg) emit_sse_reg_reg_size ((inst), (dreg), (reg), 0xf3, 0x0f, 0x2d, 8)
#define amd64_sse_cvttsd2si_reg_reg_size(inst,dreg,reg,size) emit_sse_reg_reg_size ((inst), (dreg), (reg), 0xf2, 0x0f, 0x2c, (size))
#define amd64_sse_cvtss2si_reg_reg_size(inst,dreg,reg,size) emit_sse_reg_reg_size ((inst), (dreg), (reg), 0xf3, 0x0f, 0x2c, (size))
#define amd64_sse_cvttsd2si_reg_reg(inst,dreg,reg) amd64_sse_cvttsd2si_reg_reg_size ((inst), (dreg), (reg), 8)
@ -1063,12 +1067,16 @@ typedef union {
#define amd64_sse_cvtss2sd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x5a)
#define amd64_sse_addsd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf2, 0x0f, 0x58)
#define amd64_sse_addss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x58)
#define amd64_sse_subsd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf2, 0x0f, 0x5c)
#define amd64_sse_subss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x5c)
#define amd64_sse_mulsd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf2, 0x0f, 0x59)
#define amd64_sse_mulss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x59)
#define amd64_sse_divsd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf2, 0x0f, 0x5e)
#define amd64_sse_divss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x5e)
#define amd64_sse_sqrtsd_reg_reg(inst,dreg,reg) emit_sse_reg_reg((inst), (dreg), (reg), 0xf2, 0x0f, 0x51)

View File

@ -123,7 +123,7 @@ enum {
PPC_TRAP_GE_UN = 16 + PPC_TRAP_EQ
};
#define ppc_emit32(c,x) do { *((guint32 *) (c)) = GUINT32_TO_BE (x); (c) = (gpointer)((guint8 *)(c) + sizeof (guint32));} while (0)
#define ppc_emit32(c,x) do { *((guint32 *) (c)) = (guint32) (x); (c) = (gpointer)((guint8 *)(c) + sizeof (guint32));} while (0)
#define ppc_is_imm16(val) ((((val)>> 15) == 0) || (((val)>> 15) == -1))
#define ppc_is_uimm16(val) ((glong)(val) >= 0L && (glong)(val) <= 65535L)
@ -806,11 +806,15 @@ my and Ximian's copyright to this code. ;)
} \
} G_STMT_END
#if _CALL_ELF == 2
#define ppc_load_func(c,D,V) ppc_load_sequence ((c), (D), (V))
#else
#define ppc_load_func(c,D,v) G_STMT_START { \
ppc_load_sequence ((c), ppc_r11, (guint64)(gsize)(v)); \
ppc_ldptr ((c), ppc_r2, sizeof (gpointer), ppc_r11); \
ppc_ldptr ((c), (D), 0, ppc_r11); \
ppc_load_sequence ((c), ppc_r12, (guint64)(gsize)(v)); \
ppc_ldptr ((c), ppc_r2, sizeof (gpointer), ppc_r12); \
ppc_ldptr ((c), (D), 0, ppc_r12); \
} G_STMT_END
#endif
#define ppc_load_multiple_regs(c,D,d,A) G_STMT_START { \
int __i, __o = (d); \

View File

@ -921,6 +921,7 @@ typedef struct {
#define s390_nill(c, r, v) S390_RI(c, 0xa57, r, v)
#define s390_niy(c, b, d, v) S390_SIY(c, 0xeb54, b, d, v)
#define s390_nop(c) S390_RR(c, 0x07, 0x0, 0)
#define s390_mem(c) S390_RR(c, 0x07, 0xe, 0)
#define s390_nr(c, r1, r2) S390_RR(c, 0x14, r1, r2)
#define s390_nrk(c, r1, r2) S390_RRF_1(c, 0xb9f4, r1, r2)
#define s390_ny(c, r, x, b, d) S390_RRY(c, 0xe354, r1, r2)

View File

@ -1,7 +1,2 @@
AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
noinst_LTLIBRARIES = libmonoarch-sparc.la
libmonoarch_sparc_la_SOURCES = tramp.c sparc-codegen.h
EXTRA_DIST = sparc-codegen.h

View File

@ -522,6 +522,14 @@ typedef union {
#endif /* __native_client_codegen__ */
#define x86_mfence(inst) \
do { \
x86_codegen_pre(&(inst), 3); \
*(inst)++ = 0x0f; \
*(inst)++ = 0xae; \
*(inst)++ = 0xf0; \
} while (0)
#define x86_rdtsc(inst) \
do { \
x86_codegen_pre(&(inst), 2); \

View File

@ -4,18 +4,19 @@ if HOST_WIN32
export HOST_CC
endif
if !SHARED_MONO
static_libs= \
$(top_builddir)/mono/metadata/libmonoruntime-static.la \
if SUPPORT_SGEN
metadata_lib=$(top_builddir)/mono/metadata/libmonoruntimesgen-static.la
else
metadata_lib=$(top_builddir)/mono/metadata/libmonoruntime-static.a
gc_lib=$(LIBGC_STATIC_LIBS)
endif
runtime_lib= \
$(metadata_lib) \
$(top_builddir)/mono/io-layer/libwapi.la \
$(top_builddir)/mono/utils/libmonoutils.la \
$(GLIB_LIBS) $(LIBICONV) \
$(LIBGC_STATIC_LIBS)
runtime_lib=../mini/$(LIBMONO_LA) $(static_libs)
else
runtime_lib=../mini/$(LIBMONO_LA)
endif
$(gc_lib)
if DISABLE_EXECUTABLES
bin_PROGRAMS =
@ -23,11 +24,9 @@ else
if DISABLE_LIBRARIES
bin_PROGRAMS =
else
if SUPPORT_BOEHM
bin_PROGRAMS = monodis
endif
endif
endif
noinst_LIBRARIES = libmonodis.a
@ -51,11 +50,12 @@ monodis_LDADD = \
libmonodis.a \
$(runtime_lib) \
$(LLVM_LIBS) \
$(LLVM_LDFLAGS) \
$(GLIB_LIBS) \
$(LIBICONV)
if PLATFORM_DARWIN
monodis_LDFLAGS=-framework CoreFoundation
monodis_LDFLAGS=-framework CoreFoundation -framework Foundation
endif
man_MANS = monodis.1

View File

@ -598,7 +598,8 @@ dump_table_method (MonoImage *m)
mono_metadata_decode_table_row (m, MONO_TABLE_METHOD, i - 1, cols, MONO_METHOD_SIZE);
sigblob = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
mono_metadata_decode_blob_size (sigblob, &sigblob);
method = mono_metadata_parse_method_signature_full (m, method_container ? method_container : type_container, i, sigblob, &sigblob);
method = mono_metadata_parse_method_signature_full (m, method_container ? method_container : type_container, i, sigblob, &sigblob, &error);
g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/
sig = dis_stringify_method_signature (m, method, i, method_container ? method_container : type_container, FALSE);
impl_flags = get_method_impl_flags (cols [MONO_METHOD_IMPLFLAGS]);
fprintf (output, "%d: %s (param: %d impl_flags: %s)\n", i, sig, cols [MONO_METHOD_PARAMLIST], impl_flags);

View File

@ -215,14 +215,16 @@ get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContainer *
g_string_append (res, "*");
break;
case MONO_TYPE_FNPTR:
sig = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
case MONO_TYPE_FNPTR: {
MonoError error;
sig = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr, &error);
g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/
s = dis_stringify_function_ptr (m, sig);
g_string_append (res, "method ");
g_string_append (res, s);
g_free (s);
break;
}
case MONO_TYPE_ARRAY:
ptr = get_type (m, ptr, &s, is_def, container);
g_string_append (res, s);
@ -899,7 +901,8 @@ dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method,
}
mono_metadata_decode_blob_size (sig, &sig);
method = mono_metadata_parse_method_signature_full (m, container, methoddef_row, sig, &sig);
method = mono_metadata_parse_method_signature_full (m, container, methoddef_row, sig, &sig, &error);
g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/
free_method = 1;
}

View File

@ -836,6 +836,7 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
}
for (i = start; i < end; i++){
MonoError error;
MonoMethodSignature *ms;
MonoGenericContainer *container;
char *flags, *impl_flags;
@ -862,13 +863,14 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
container = type_container;
}
ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig);
ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig, &error);
if (ms != NULL){
sig_str = dis_stringify_method_signature (m, ms, i + 1, container, FALSE);
method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
} else {
sig_str = NULL;
method_name = g_strdup ("<NULL METHOD SIGNATURE>");
mono_error_cleanup (&error);
}
fprintf (output, " // method line %d\n", i + 1);

View File

@ -0,0 +1,26 @@
2006-01-25 Ankit Jain <jankit@novell.com>
* ambiguous-gen-params.il: New test case for type/method with
ambiguous generic parameters.
2006-01-16 Ankit Jain <jankit@novell.com>
* gen-type.cs: New test case for handling a MemberRef with
a TypeSpec parent.
2005-11-23 Ankit Jain <jankit@novell.com>
* gen-cattr.cs: New test case for custom attributes on
type parameters.
2005-11-15 Ankit Jain <jankit@novell.com>
* test1.cs, test2.cs, test3.cs: New test cases for Bug #76671.
2005-11-08 Ankit Jain <jankit@novell.com>
* gen-dump-table.cs: New test case (for r52695).
2005-10-28 Ankit Jain <jankit@novell.com>
* gen-prop.cs: New test case (for r52316).

View File

@ -0,0 +1,53 @@
// Test for type/method having type parameters with identical names
//
// Roundtrip with ilasm2/monodis should yield same
// meth <A,A, B> (!!0 _a1, !!1 _a2, !1 _t, !!B _b)
.assembly extern mscorlib
{
.ver 2:0:0:0
}
.assembly 'ambiguous-gen-params'
{
.custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (
01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.ver 0:0:0:0
}
.module 'ambiguous-gen-params.dll'
.class private auto ansi beforefieldinit g`1<T, T>
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname
instance default void .ctor () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void object::.ctor()
IL_0006: ret
}
.method public static hidebysig
default void meth <A,A, B> (!!0 _a1, !!1 _a2, !1 _t, !!B _b) cil managed
{
ret
}
.method public static hidebysig
default !!A foo<A,B> (!!B _b, !1 _t, !!A _a) cil managed
{
.maxstack 1
.locals init (
!!A V_0)
IL_0000: ldloca.s 0
IL_0002: initobj !!0
IL_0008: ldloc.0
IL_0009: ret
}
}

View File

@ -0,0 +1,17 @@
/* Custom attributes for type parameters */
using System;
[AttributeUsage(AttributeTargets.GenericParameter)]
class GenParAttribute : Attribute {
}
class cons <[GenPar] A> {
public void abc <[GenPar] M> () {
}
}
class Test {
public static void Main ()
{
}
}

View File

@ -0,0 +1,21 @@
//Test for dumping method table for generic types and generic methods
//monodis --method
class a
{
void a_foo <U> (U u)
{
}
}
class g <T>
{
T foo2 (int i, T t)
{
return default (T);
}
T foo <U> (U u, int i)
{
return default (T);
}
}

View File

@ -0,0 +1,7 @@
//Property using a generic param
class g<T>
{
public T abc {
get { return default (T); }
}
}

View File

@ -0,0 +1,16 @@
// Test for a MemberRef with a TypeSpec parent
class g<T>
{
public void foo <A> (A _a)
{
}
}
class test {
public static void Main ()
{
g<int> _g = new g<int> ();
_g.foo ("abc");
}
}

23
mta-mono/vendor/mono/dis/tests/test1.cs vendored Normal file
View File

@ -0,0 +1,23 @@
/* Bug #76671
Note: gmcs currently emits duplicate TypeSpecs, so this
case doesn't get exposed, so use csc compiled
assemblies till gmcs is fixed.
*/
class X<T1> {
public static void Xfoo () {
X<T1>.Xfoo();
}
}
class Y<T2> {
public static void Yfoo () {
X<T2>.Xfoo();
}
}
class Test {
static void Main ()
{
}
}

50
mta-mono/vendor/mono/dis/tests/test2.cs vendored Normal file
View File

@ -0,0 +1,50 @@
/* Bug #76671
Note: gmcs currently emits duplicate TypeSpecs, so this
case doesn't get exposed, so use csc compiled
assemblies till gmcs is fixed.
Array of type params
*/
using System;
class list <T> {
public static void bar ()
{
gen<int, T[][]>.foo ();
gen<int[][], T>.foo ();
gen<int, T[][,]>.foo ();
gen<T[,,], int>.foo ();
}
}
class list_two <D> {
public static void bar ()
{
gen<int, D[][]>.foo ();
gen<int[][], D>.foo ();
gen<int, D[][,]>.foo ();
gen<D[,,], int>.foo ();
}
}
class list_three <F> {
public static void bar ()
{
gen<int, F[][]>.foo ();
gen<int[][], F>.foo ();
gen<int, F[][,]>.foo ();
gen<F[,,], int>.foo ();
}
}
class gen <Q, R> {
public static void foo ()
{
}
}
class Test {
public static void Main ()
{
}
}

25
mta-mono/vendor/mono/dis/tests/test3.cs vendored Normal file
View File

@ -0,0 +1,25 @@
/* Bug #76671
Note: gmcs currently emits duplicate TypeSpecs, so this
case doesn't get exposed, so use csc compiled
assemblies till gmcs is fixed.
*/
using System;
class X<T1> {
public static void Xfoo () {
Console.WriteLine (typeof (T1).ToString ());
}
}
class Y<T2> {
public static void Yfoo () {
Console.WriteLine (typeof (T2).ToString ());
}
}
class Test {
static void Main ()
{
}
}

View File

@ -5,7 +5,8 @@ AM_CPPFLAGS = \
$(GLIB_CFLAGS) \
$(LIBGC_CPPFLAGS) \
-DMONO_BINDIR=\""$(bindir)"\" \
-I$(top_srcdir)
-I$(top_srcdir) \
$(SHARED_CFLAGS)
libwapiincludedir = $(includedir)/mono-$(API_VER)/mono/io-layer
@ -34,7 +35,8 @@ OTHER_H = \
uglify.h \
versioninfo.h \
wait.h \
wapi.h
wapi.h \
wapi-remap.h
OTHER_SRC = \
access.h \

View File

@ -10,7 +10,6 @@
#include <config.h>
#include <glib.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

View File

@ -84,7 +84,7 @@ extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean pol
extern int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable);
extern int _wapi_handle_timedwait_signal_handle (gpointer handle,
struct timespec *timeout, gboolean alertable, gboolean poll);
extern gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode,
extern gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
guint32 new_sharemode,
guint32 new_access,
guint32 *old_sharemode,

View File

@ -13,7 +13,9 @@
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
@ -220,16 +222,7 @@ static void handle_cleanup (void)
int
wapi_getdtablesize (void)
{
#ifdef HAVE_GETRLIMIT
struct rlimit limit;
int res;
res = getrlimit (RLIMIT_NOFILE, &limit);
g_assert (res == 0);
return limit.rlim_cur;
#else
return getdtablesize ();
#endif
return eg_getdtablesize ();
}
/*
@ -286,13 +279,6 @@ wapi_init (void)
_wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex;
wapi_processes_init ();
/* Using atexit here instead of an explicit function call in
* a cleanup routine lets us cope when a third-party library
* calls exit (eg if an X client loses the connection to its
* server.)
*/
mono_atexit (handle_cleanup);
}
void
@ -305,6 +291,7 @@ wapi_cleanup (void)
_wapi_error_cleanup ();
_wapi_thread_cleanup ();
wapi_processes_cleanup ();
handle_cleanup ();
}
static void _wapi_handle_init_shared (struct _WapiHandleShared *handle,
@ -1652,7 +1639,7 @@ wapi_share_info_hash (gconstpointer data)
return s->inode;
}
gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode,
gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
guint32 new_sharemode,
guint32 new_access,
guint32 *old_sharemode,
@ -1819,8 +1806,6 @@ static void _wapi_handle_check_share_by_pid (struct _WapiFileShare *share_info)
void _wapi_handle_check_share (struct _WapiFileShare *share_info, int fd)
{
gboolean found = FALSE, proc_fds = FALSE;
pid_t self = _wapi_getpid ();
int pid;
int thr_ret, i;
/* Prevents entries from expiring under us if we remove this

View File

@ -27,8 +27,6 @@
#include <sys/mount.h>
#endif
#include <sys/types.h>
#include <dirent.h>
#include <fnmatch.h>
#include <stdio.h>
#include <utime.h>
#ifdef __linux__
@ -1036,6 +1034,7 @@ static void console_close (gpointer handle, gpointer data)
g_free (console_handle->filename);
if (fd > 2)
close (fd);
}

View File

@ -50,6 +50,7 @@ struct MonoProcess {
* the process has exited, so that the information there isn't lost.
*/
gpointer handle;
gboolean freeable;
struct MonoProcess *next;
};

View File

@ -19,20 +19,31 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#include <sys/wait.h>
#endif
#include <sys/time.h>
#include <sys/resource.h>
#include <fcntl.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <ctype.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_MKDEV_H
#include <sys/mkdev.h>
#endif
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
/* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */
#ifdef __APPLE__
#include <TargetConditionals.h>
@ -81,7 +92,7 @@
#include <mono/utils/mono-signal-handler.h>
/* The process' environment strings */
#if defined(__APPLE__) && !defined (__arm__)
#if defined(__APPLE__) && !defined (__arm__) && !defined (__aarch64__)
/* Apple defines this in crt_externs.h but doesn't provide that header for
* arm-apple-darwin9. We'll manually define the symbol on Apple as it does
* in fact exist on all implementations (so far)
@ -137,7 +148,6 @@ static void process_add_sigchld_handler (void);
* signal handler)
*/
static struct MonoProcess *mono_processes = NULL;
static volatile gint32 mono_processes_read_lock = 0;
static volatile gint32 mono_processes_cleaning_up = 0;
static mono_mutex_t mono_processes_mutex;
static void mono_processes_cleanup (void);
@ -489,6 +499,21 @@ CreateProcessWithLogonW (const gunichar2 *username,
return CreateProcess (appname, cmdline, NULL, NULL, FALSE, create_flags, env, cwd, startup, process_info);
}
static gboolean
is_readable_or_executable (const char *prog)
{
struct stat buf;
int a = access (prog, R_OK);
int b = access (prog, X_OK);
if (a != 0 && b != 0)
return FALSE;
if (stat (prog, &buf))
return FALSE;
if (S_ISREG (buf.st_mode))
return TRUE;
return FALSE;
}
static gboolean
is_executable (const char *prog)
{
@ -621,7 +646,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
prog = g_strdup (unquoted);
/* Executable existing ? */
if (!is_executable (prog)) {
if (!is_readable_or_executable (prog)) {
DEBUG ("%s: Couldn't find executable %s",
__func__, prog);
g_free (unquoted);
@ -637,8 +662,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
prog = g_strdup_printf ("%s/%s", curdir, unquoted);
g_free (curdir);
/* And make sure it's executable */
if (!is_executable (prog)) {
/* And make sure it's readable */
if (!is_readable_or_executable (prog)) {
DEBUG ("%s: Couldn't find executable %s",
__func__, prog);
g_free (unquoted);
@ -729,7 +754,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
prog = g_strdup (token);
/* Executable existing ? */
if (!is_executable (prog)) {
if (!is_readable_or_executable (prog)) {
DEBUG ("%s: Couldn't find executable %s",
__func__, token);
g_free (token);
@ -750,8 +775,10 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
/* I assume X_OK is the criterion to use,
* rather than F_OK
*
* X_OK is too strict *if* the target is a CLR binary
*/
if (!is_executable (prog)) {
if (!is_readable_or_executable (prog)) {
g_free (prog);
prog = g_find_program_in_path (token);
if (prog == NULL) {
@ -808,6 +835,13 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
goto free_strings;
}
}
} else {
if (!is_executable (prog)) {
DEBUG ("%s: Executable permisson not set on %s", __func__, prog);
g_free (prog);
SetLastError (ERROR_ACCESS_DENIED);
goto free_strings;
}
}
if (args_after_prog != NULL && *args_after_prog) {
@ -1241,6 +1275,11 @@ GetExitCodeProcess (gpointer process, guint32 *code)
return FALSE;
}
if (process_handle->id == _wapi_getpid ()) {
*code = STILL_ACTIVE;
return TRUE;
}
/* A process handle is only signalled if the process has exited
* and has been waited for */
@ -1317,8 +1356,8 @@ typedef struct
gpointer address_end;
char *perms;
gpointer address_offset;
dev_t device;
ino_t inode;
guint64 device;
guint64 inode;
char *filename;
} WapiProcModule;
@ -1387,7 +1426,7 @@ static GSList *load_modules (void)
mod->perms = g_strdup ("r--p");
mod->address_offset = 0;
mod->device = makedev (0, 0);
mod->inode = (ino_t) i;
mod->inode = i;
mod->filename = g_strdup (name);
if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
@ -1439,7 +1478,7 @@ static GSList *load_modules (void)
info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
mod->perms = g_strdup ("r--p");
mod->address_offset = 0;
mod->inode = (ino_t) i;
mod->inode = i;
mod->filename = g_strdup (info->dlpi_name);
DEBUG ("%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
@ -1501,8 +1540,8 @@ static GSList *load_modules (FILE *fp)
char *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5];
gpointer address_start, address_end, address_offset;
guint32 maj_dev, min_dev;
ino_t inode;
dev_t device;
guint64 inode;
guint64 device;
while (fgets (buf, sizeof(buf), fp)) {
p = buf;
@ -1575,7 +1614,7 @@ static GSList *load_modules (FILE *fp)
if (!g_ascii_isxdigit (*inode_start)) {
continue;
}
inode = (ino_t)strtol (inode_start, &endp, 10);
inode = (guint64)strtol (inode_start, &endp, 10);
p = endp;
if (!g_ascii_isspace (*p)) {
continue;
@ -2395,9 +2434,9 @@ mono_processes_cleanup (void)
{
struct MonoProcess *mp;
struct MonoProcess *prev = NULL;
struct MonoProcess *candidate = NULL;
GSList *finished = NULL;
GSList *l;
gpointer unref_handle;
int spin;
DEBUG ("%s", __func__);
@ -2405,9 +2444,8 @@ mono_processes_cleanup (void)
if (InterlockedCompareExchange (&mono_processes_cleaning_up, 1, 0) != 0)
return;
mp = mono_processes;
while (mp != NULL) {
if (mp->pid == 0 && mp->handle != NULL) {
for (mp = mono_processes; mp; mp = mp->next) {
if (mp->pid == 0 && mp->handle) {
/* This process has exited and we need to remove the artifical ref
* on the handle */
mono_mutex_lock (&mono_processes_mutex);
@ -2416,9 +2454,7 @@ mono_processes_cleanup (void)
mono_mutex_unlock (&mono_processes_mutex);
if (unref_handle)
_wapi_handle_unref (unref_handle);
continue;
}
mp = mp->next;
}
/*
@ -2427,62 +2463,44 @@ mono_processes_cleanup (void)
* asynchronously. The handler requires that the mono_processes list
* remain valid.
*/
mp = mono_processes;
spin = 0;
while (mp != NULL) {
if ((mp->handle_count == 0 && mp->pid == 0) || candidate != NULL) {
if (spin > 0) {
_wapi_handle_spin (spin);
spin <<= 1;
}
/* We've found a candidate */
mono_mutex_lock (&mono_processes_mutex);
mp = mono_processes;
while (mp) {
if (mp->handle_count == 0 && mp->freeable) {
/*
* Unlink the entry.
* This code can run parallel with the sigchld handler, but the
* modifications it makes are safe.
*/
if (candidate == NULL) {
/* unlink it */
if (mp == mono_processes) {
if (mp == mono_processes)
mono_processes = mp->next;
} else {
else
prev->next = mp->next;
}
candidate = mp;
}
finished = g_slist_prepend (finished, mp);
/* It's still safe to traverse the structure.*/
mono_memory_barrier ();
if (mono_processes_read_lock != 0) {
/* The sigchld handler is watching us. Spin a bit and try again */
if (spin == 0) {
spin = 1;
} else if (spin >= 8) {
/* Just give up for now */
mono_mutex_unlock (&mono_processes_mutex);
break;
}
mp = mp->next;
} else {
/* We've modified the list of processes, and we know the sigchld handler
* isn't executing, so even if it executes at any moment, it'll see the
* new version of the list. So now we can free the candidate. */
DEBUG ("%s: freeing candidate %p", __func__, candidate);
mp = candidate->next;
MONO_SEM_DESTROY (&candidate->exit_sem);
g_free (candidate);
candidate = NULL;
}
mono_mutex_unlock (&mono_processes_mutex);
continue;
}
spin = 0;
prev = mp;
mp = mp->next;
}
}
mono_memory_barrier ();
for (l = finished; l; l = l->next) {
/*
* All the entries in the finished list are unlinked from mono_processes, and
* they have the 'finished' flag set, which means the sigchld handler is done
* accessing them.
*/
mp = l->data;
MONO_SEM_DESTROY (&mp->exit_sem);
g_free (mp);
}
g_slist_free (finished);
mono_mutex_unlock (&mono_processes_mutex);
DEBUG ("%s done", __func__);
@ -2513,8 +2531,6 @@ MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, sigi
DEBUG ("SIG CHILD handler for pid: %i\n", info->si_pid);
InterlockedIncrement (&mono_processes_read_lock);
do {
do {
pid = waitpid (-1, &status, WNOHANG);
@ -2524,20 +2540,25 @@ MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, sigi
break;
DEBUG ("child ended: %i", pid);
p = mono_processes;
while (p != NULL) {
/*
* This can run concurrently with the code in the rest of this module.
*/
for (p = mono_processes; p; p = p->next) {
if (p->pid == pid) {
break;
}
}
if (p) {
p->pid = 0; /* this pid doesn't exist anymore, clear it */
p->status = status;
MONO_SEM_POST (&p->exit_sem);
break;
}
p = p->next;
mono_memory_barrier ();
/* Mark this as freeable, the pointer becomes invalid afterwards */
p->freeable = TRUE;
}
} while (1);
InterlockedDecrement (&mono_processes_read_lock);
DEBUG ("SIG CHILD handler: done looping.");
}

View File

@ -35,7 +35,6 @@
#define _wapi_setsockopt setsockopt
#define _wapi_shutdown shutdown
#define _wapi_socket WSASocket
#define _wapi_gethostbyname gethostbyname
#define _wapi_select select
/* No need to wrap FD_ZERO because it doesnt involve file
@ -45,6 +44,7 @@
#define _wapi_FD_ISSET FD_ISSET
#define _wapi_FD_SET FD_SET
#define _wapi_cleanup_networking() ;
#else
#define WSA_FLAG_OVERLAPPED 0x01
@ -76,7 +76,6 @@ extern int _wapi_setsockopt(guint32 handle, int level, int optname,
extern int _wapi_shutdown(guint32 handle, int how);
extern guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
guint32 unused2, guint32 flags);
extern struct hostent *_wapi_gethostbyname(const char *hostname);
#ifdef HAVE_SYS_SELECT_H
extern int _wapi_select(int nfds, fd_set *readfds, fd_set *writefds,
@ -87,5 +86,6 @@ extern int _wapi_FD_ISSET(guint32 handle, fd_set *set);
extern void _wapi_FD_SET(guint32 handle, fd_set *set);
#endif
extern void _wapi_cleanup_networking (void);
#endif /* HOST_WIN32 */

View File

@ -45,11 +45,13 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <arpa/inet.h>
#ifdef HAVE_SYS_SENDFILE_H
#include <sys/sendfile.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
@ -57,7 +59,6 @@
#define DEBUG(...)
#endif
static guint32 startup_count=0;
static guint32 in_cleanup = 0;
static void socket_close (gpointer handle, gpointer data);
@ -85,11 +86,6 @@ static void socket_close (gpointer handle, gpointer data)
DEBUG ("%s: closing socket handle %p", __func__, handle);
if (startup_count == 0 && !in_cleanup) {
WSASetLastError (WSANOTINITIALISED);
return;
}
/* Shutdown the socket for reading, to interrupt any potential
* receives that may be blocking for data. See bug 75705.
*/
@ -112,33 +108,6 @@ static void socket_close (gpointer handle, gpointer data)
socket_handle->saved_error = 0;
}
int WSAStartup(guint32 requested, WapiWSAData *data)
{
if (data == NULL) {
return(WSAEFAULT);
}
/* Insist on v2.0+ */
if (requested < MAKEWORD(2,0)) {
return(WSAVERNOTSUPPORTED);
}
startup_count++;
/* I've no idea what is the minor version of the spec I read */
data->wHighVersion = MAKEWORD(2,2);
data->wVersion = requested < data->wHighVersion? requested:
data->wHighVersion;
DEBUG ("%s: high version 0x%x", __func__, data->wHighVersion);
strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
return(0);
}
static gboolean
cleanup_close (gpointer handle, gpointer data)
{
@ -146,19 +115,13 @@ cleanup_close (gpointer handle, gpointer data)
return TRUE;
}
int WSACleanup(void)
void _wapi_cleanup_networking(void)
{
DEBUG ("%s: cleaning up", __func__);
if (--startup_count) {
/* Do nothing */
return(0);
}
in_cleanup = 1;
_wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
in_cleanup = 0;
return(0);
}
void WSASetLastError(int error)
@ -193,11 +156,6 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
gboolean ok;
int new_fd;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(INVALID_SOCKET);
}
if (addr != NULL && *addrlen < sizeof(struct sockaddr)) {
WSASetLastError (WSAEFAULT);
return(INVALID_SOCKET);
@ -266,11 +224,6 @@ int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -296,11 +249,6 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
gboolean ok;
gint errnum;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -346,7 +294,7 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
}
fds.fd = fd;
fds.events = POLLOUT;
fds.events = MONO_POLLOUT;
while (mono_poll (&fds, 1, -1) == -1 &&
!_wapi_thread_cur_apc_pending ()) {
if (errno != EINTR) {
@ -400,11 +348,6 @@ int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -430,11 +373,6 @@ int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -465,11 +403,6 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
struct _WapiHandle_socket *socket_handle;
gboolean ok;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -529,11 +462,6 @@ int _wapi_listen(guint32 fd, int backlog)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -566,11 +494,6 @@ int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
gboolean ok;
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -628,11 +551,6 @@ _wapi_recvmsg(guint32 fd, struct msghdr *msg, int recv_flags)
gboolean ok;
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -670,11 +588,6 @@ int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -712,11 +625,6 @@ int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -745,11 +653,6 @@ _wapi_sendmsg(guint32 fd, const struct msghdr *msg, int send_flags)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -784,11 +687,6 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
#endif
struct timeval tv;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -851,11 +749,6 @@ int _wapi_shutdown(guint32 fd, int how)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -980,45 +873,6 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
return(fd);
}
struct hostent *_wapi_gethostbyname(const char *hostname)
{
struct hostent *he;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(NULL);
}
he = gethostbyname (hostname);
if (he == NULL) {
DEBUG ("%s: gethostbyname error: %s", __func__,
strerror (h_errno));
switch(h_errno) {
case HOST_NOT_FOUND:
WSASetLastError (WSAHOST_NOT_FOUND);
break;
#if NO_ADDRESS != NO_DATA
case NO_ADDRESS:
#endif
case NO_DATA:
WSASetLastError (WSANO_DATA);
break;
case NO_RECOVERY:
WSASetLastError (WSANO_RECOVERY);
break;
case TRY_AGAIN:
WSASetLastError (WSATRY_AGAIN);
break;
default:
g_warning ("%s: Need to translate %d into winsock error", __func__, h_errno);
break;
}
}
return(he);
}
static gboolean socket_disconnect (guint32 fd)
{
struct _WapiHandle_socket *socket_handle;
@ -1165,11 +1019,6 @@ TransmitFile (guint32 socket, gpointer file, guint32 bytes_to_write, guint32 byt
gpointer sock = GUINT_TO_POINTER (socket);
gint ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return FALSE;
}
if (_wapi_handle_type (sock) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return FALSE;
@ -1219,11 +1068,6 @@ WSAIoctl (guint32 fd, gint32 command,
int ret;
gchar *buffer = NULL;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return SOCKET_ERROR;
@ -1362,11 +1206,6 @@ int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
@ -1439,11 +1278,6 @@ int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
{
int ret, maxfd;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
for (maxfd = FD_SETSIZE-1; maxfd >= 0; maxfd--) {
if ((readfds && FD_ISSET (maxfd, readfds)) ||
(writefds && FD_ISSET (maxfd, writefds)) ||

View File

@ -78,9 +78,6 @@ typedef gboolean (*WapiTransmitFileFn)(guint32, gpointer, guint32, guint32,
WapiTransmitFileBuffers *,
WapiTransmitFileFlags);
extern int WSAStartup(guint32 requested, WapiWSAData *data);
extern int WSACleanup(void);
extern void WSASetLastError(int error);
extern int WSAGetLastError(void);
extern int closesocket(guint32 handle);

View File

@ -178,8 +178,8 @@ struct _WapiFileShare
#ifdef WAPI_FILE_SHARE_PLATFORM_EXTRA_DATA
WAPI_FILE_SHARE_PLATFORM_EXTRA_DATA
#endif
dev_t device;
ino_t inode;
guint64 device;
guint64 inode;
pid_t opened_by_pid;
guint32 sharemode;
guint32 access;

View File

@ -0,0 +1,107 @@
/*
* wapi-remap.h: io-layer symbol remapping support
*
* (C) 2014 Xamarin, Inc.
*/
#ifndef __WAPI_REMAP_H__
#define __WAPI_REMAP_H__
/*
* The windows function names used by the io-layer can collide with symbols in system and 3rd party libs, esp. on osx/ios. So remap them to
* wapi_<funcname>.
*/
#define GetThreadContext wapi_GetThreadContext
#define CreateEvent wapi_CreateEvent
#define PulseEvent wapi_PulseEvent
#define ResetEvent wapi_ResetEvent
#define SetEvent wapi_SetEvent
#define OpenEvent wapi_OpenEvent
#define CloseHandle wapi_CloseHandle
#define DuplicateHandle wapi_DuplicateHandle
#define CreateFile wapi_CreateFile
#define DeleteFile wapi_DeleteFile
#define GetStdHandle wapi_GetStdHandle
#define ReadFile wapi_ReadFile
#define WriteFile wapi_WriteFile
#define FlushFileBuffers wapi_FlushFileBuffers
#define SetEndOfFile wapi_SetEndOfFile
#define SetFilePointer wapi_SetFilePointer
#define GetFileType wapi_GetFileType
#define GetFileSize wapi_GetFileSize
#define GetFileTime wapi_GetFileTime
#define SetFileTime wapi_SetFileTime
#define FileTimeToSystemTime wapi_FileTimeToSystemTime
#define FindFirstFile wapi_FindFirstFile
#define FindNextFile wapi_FindNextFile
#define FindClose wapi_FindClose
#define CreateDirectory wapi_CreateDirectory
#define RemoveDirectory wapi_RemoveDirectory
#define MoveFile wapi_MoveFile
#define CopyFile wapi_CopyFile
#define ReplaceFile wapi_ReplaceFile
#define GetFileAttributes wapi_GetFileAttributes
#define GetFileAttributesEx wapi_GetFileAttributesEx
#define SetFileAttributes wapi_SetFileAttributes
#define GetCurrentDirectory wapi_GetCurrentDirectory
#define SetCurrentDirectory wapi_SetCurrentDirectory
#define CreatePipe wapi_CreatePipe
#define GetTempPath wapi_GetTempPath
#define GetLogicalDriveStrings wapi_GetLogicalDriveStrings
#define GetDiskFreeSpaceEx wapi_GetDiskFreeSpaceEx
#define GetDriveType wapi_GetDriveType
#define LockFile wapi_LockFile
#define UnlockFile wapi_UnlockFile
#define GetVolumeInformation wapi_GetVolumeInformation
#define FormatMessage wapi_FormatMessage
#define CreateMutex wapi_CreateMutex
#define ReleaseMutex wapi_ReleaseMutex
#define OpenMutex wapi_OpenMutex
#define ShellExecuteEx wapi_ShellExecuteEx
#define CreateProcess wapi_CreateProcess
#define CreateProcessWithLogonW wapi_CreateProcessWithLogonW
#define GetCurrentProcess wapi_GetCurrentProcess
#define GetProcessId wapi_GetProcessId
#define CloseProcess wapi_CloseProcess
#define OpenProcess wapi_OpenProcess
#define GetExitCodeProcess wapi_GetExitCodeProcess
#define GetProcessTimes wapi_GetProcessTimes
#define EnumProcessModules wapi_EnumProcessModules
#define GetModuleBaseName wapi_GetModuleBaseName
#define GetModuleFileNameEx wapi_GetModuleFileNameEx
#define GetModuleInformation wapi_GetModuleInformation
#define GetProcessWorkingSetSize wapi_GetProcessWorkingSetSize
#define SetProcessWorkingSetSize wapi_SetProcessWorkingSetSize
#define TerminateProcess wapi_TerminateProcess
#define GetPriorityClass wapi_GetPriorityClass
#define SetPriorityClass wapi_SetPriorityClass
#define ImpersonateLoggedOnUser wapi_ImpersonateLoggedOnUser
#define RevertToSelf wapi_RevertToSelf
#define CreateSemaphore wapi_CreateSemaphore
#define ReleaseSemaphore wapi_ReleaseSemaphore
#define OpenSemaphore wapi_OpenSemaphore
#define WSASetLastError wapi_WSASetLastError
#define WSAGetLastError wapi_WSAGetLastError
#define WSAIoctl wapi_WSAIoctl
#define WSARecv wapi_WSARecv
#define WSASend wapi_WSASend
#define GetSystemInfo wapi_GetSystemInfo
#define GetCurrentThreadId wapi_GetCurrentThreadId
#define Sleep wapi_Sleep
#define SleepEx wapi_SleepEx
#define QueryPerformanceCounter wapi_QueryPerformanceCounter
#define QueryPerformanceFrequency wapi_QueryPerformanceFrequency
#define GetTickCount wapi_GetTickCount
#define GetFileVersionInfoSize wapi_GetFileVersionInfoSize
#define GetFileVersionInfo wapi_GetFileVersionInfo
#define VerQueryValue wapi_VerQueryValue
#define VerLanguageName wapi_VerLanguageName
#define WaitForSingleObject wapi_WaitForSingleObject
#define WaitForSingleObjectEx wapi_WaitForSingleObjectEx
#define SignalObjectAndWait wapi_SignalObjectAndWait
#define WaitForMultipleObjects wapi_WaitForMultipleObjects
#define WaitForMultipleObjectsEx wapi_WaitForMultipleObjectsEx
#define WaitForInputIdle wapi_WaitForInputIdle
#endif /* __WAPI_REMAP_H__ */

View File

@ -10,6 +10,7 @@
#ifndef _WAPI_WAPI_H_
#define _WAPI_WAPI_H_
#include <mono/io-layer/wapi-remap.h>
#include <mono/io-layer/types.h>
#include <mono/io-layer/macros.h>
#include <mono/io-layer/handles.h>

View File

@ -44,7 +44,6 @@
#include <glib.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -14,7 +14,6 @@
#include <glib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <sched.h>
#include <sys/time.h>
#include <errno.h>

View File

@ -25,7 +25,11 @@ enum {
#ifdef USED_CROSS_COMPILER_OFFSETS
#define MONO_STRUCT_OFFSET(struct,field) MONO_OFFSET_ ## struct ## _ ## field
#else
#if defined(HAS_CROSS_COMPILER_OFFSETS) || defined(MONO_CROSS_COMPILE)
#define MONO_STRUCT_OFFSET(struct,field) (MONO_OFFSET_ ## struct ## _ ## field == -1, G_STRUCT_OFFSET (struct,field))
#else
#define MONO_STRUCT_OFFSET(struct,field) G_STRUCT_OFFSET (struct,field)
#endif
#endif
#endif

View File

@ -78,7 +78,7 @@
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
#define MONO_CORLIB_VERSION 111
#define MONO_CORLIB_VERSION 117
typedef struct
{
@ -106,10 +106,6 @@ static MonoAssembly *
mono_domain_assembly_search (MonoAssemblyName *aname,
gpointer user_data);
static MonoAssembly *
mono_domain_assembly_postload_search (MonoAssemblyName *aname,
gpointer user_data);
static void
mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data);
@ -234,8 +230,8 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
mono_install_assembly_refonly_preload_hook (mono_domain_assembly_preload, GUINT_TO_POINTER (TRUE));
mono_install_assembly_search_hook (mono_domain_assembly_search, GUINT_TO_POINTER (FALSE));
mono_install_assembly_refonly_search_hook (mono_domain_assembly_search, GUINT_TO_POINTER (TRUE));
mono_install_assembly_postload_search_hook (mono_domain_assembly_postload_search, GUINT_TO_POINTER (FALSE));
mono_install_assembly_postload_refonly_search_hook (mono_domain_assembly_postload_search, GUINT_TO_POINTER (TRUE));
mono_install_assembly_postload_search_hook ((void*)mono_domain_assembly_postload_search, GUINT_TO_POINTER (FALSE));
mono_install_assembly_postload_refonly_search_hook ((void*)mono_domain_assembly_postload_search, GUINT_TO_POINTER (TRUE));
mono_install_assembly_load_hook (mono_domain_fire_assembly_load, NULL);
mono_install_lookup_dynamic_token (mono_reflection_lookup_dynamic_token);
@ -466,8 +462,6 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
MonoDomain *data;
char *shadow_location;
MONO_ARCH_SAVE_REGS;
adclass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
/* FIXME: pin all those objects */
@ -616,15 +610,12 @@ ves_icall_System_AppDomain_GetData (MonoAppDomain *ad, MonoString *name)
MonoObject *o;
char *str;
MONO_ARCH_SAVE_REGS;
MONO_CHECK_ARG_NULL (name, NULL);
g_assert (ad != NULL);
add = ad->data;
g_assert (add != NULL);
if (name == NULL)
mono_raise_exception (mono_get_exception_argument_null ("name"));
str = mono_string_to_utf8 (name);
mono_domain_lock (add);
@ -664,15 +655,12 @@ ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObj
{
MonoDomain *add;
MONO_ARCH_SAVE_REGS;
MONO_CHECK_ARG_NULL (name,);
g_assert (ad != NULL);
add = ad->data;
g_assert (add != NULL);
if (name == NULL)
mono_raise_exception (mono_get_exception_argument_null ("name"));
mono_domain_lock (add);
mono_g_hash_table_insert (add->env, name, data);
@ -683,8 +671,6 @@ ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObj
MonoAppDomainSetup *
ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
{
MONO_ARCH_SAVE_REGS;
g_assert (ad != NULL);
g_assert (ad->data != NULL);
@ -694,8 +680,6 @@ ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
MonoString *
ves_icall_System_AppDomain_getFriendlyName (MonoAppDomain *ad)
{
MONO_ARCH_SAVE_REGS;
g_assert (ad != NULL);
g_assert (ad->data != NULL);
@ -707,8 +691,6 @@ ves_icall_System_AppDomain_getCurDomain ()
{
MonoDomain *add = mono_domain_get ();
MONO_ARCH_SAVE_REGS;
return add->domain;
}
@ -717,8 +699,6 @@ ves_icall_System_AppDomain_getRootDomain ()
{
MonoDomain *root = mono_get_root_domain ();
MONO_ARCH_SAVE_REGS;
return root->domain;
}
@ -855,7 +835,7 @@ MonoAppDomain *
ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
{
#ifdef DISABLE_APPDOMAINS
mono_raise_exception (mono_get_exception_not_supported ("AppDomain creation is not supported on this runtime."));
mono_set_pending_exception (mono_get_exception_not_supported ("AppDomain creation is not supported on this runtime."));
return NULL;
#else
char *fname = mono_string_to_utf8 (friendly_name);
@ -878,8 +858,6 @@ ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad, MonoBoolean refonly
int i;
GPtrArray *assemblies;
MONO_ARCH_SAVE_REGS;
if (!System_Reflection_Assembly)
System_Reflection_Assembly = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "Assembly");
@ -913,12 +891,12 @@ ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad, MonoBoolean refonly
}
MonoReflectionAssembly *
mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, gboolean refonly)
mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly)
{
MonoClass *klass;
MonoMethod *method;
MonoBoolean isrefonly;
gpointer params [2];
gpointer params [3];
if (mono_runtime_get_no_exec ())
return NULL;
@ -936,15 +914,15 @@ mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, gboolean refon
isrefonly = refonly ? 1 : 0;
params [0] = fname;
params [1] = &isrefonly;
params [1] = (requesting) ? mono_assembly_get_object (domain, requesting) : NULL;
params [2] = &isrefonly;
return (MonoReflectionAssembly *) mono_runtime_invoke (method, domain->domain, params, NULL);
}
static MonoAssembly *
mono_domain_assembly_postload_search (MonoAssemblyName *aname,
gpointer user_data)
MonoAssembly *
mono_domain_assembly_postload_search (MonoAssemblyName *aname, MonoAssembly *requesting,
gboolean refonly)
{
gboolean refonly = GPOINTER_TO_UINT (user_data);
MonoReflectionAssembly *assembly;
MonoDomain *domain = mono_domain_get ();
char *aname_str;
@ -958,7 +936,7 @@ mono_domain_assembly_postload_search (MonoAssemblyName *aname,
g_free (aname_str);
return NULL;
}
assembly = mono_try_assembly_resolve (domain, str, refonly);
assembly = mono_try_assembly_resolve (domain, str, requesting, refonly);
g_free (aname_str);
if (assembly)
@ -1899,18 +1877,17 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean re
MonoImageOpenStatus status = MONO_IMAGE_OK;
MonoAssembly *ass;
MONO_ARCH_SAVE_REGS;
if (fname == NULL) {
MonoException *exc = mono_get_exception_argument_null ("assemblyFile");
mono_raise_exception (exc);
mono_set_pending_exception (exc);
return NULL;
}
name = filename = mono_string_to_utf8 (fname);
ass = mono_assembly_open_full (filename, &status, refOnly);
if (!ass){
if (!ass) {
MonoException *exc;
if (status == MONO_IMAGE_IMAGE_INVALID)
@ -1918,7 +1895,8 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean re
else
exc = mono_get_exception_file_not_found2 (NULL, fname);
g_free (name);
mono_raise_exception (exc);
mono_set_pending_exception (exc);
return NULL;
}
g_free (name);
@ -1940,7 +1918,7 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad,
MonoImage *image = mono_image_open_from_data_full (mono_array_addr (raw_assembly, gchar, 0), raw_assembly_len, TRUE, NULL, refonly);
if (!image) {
mono_raise_exception (mono_get_exception_bad_image_format (""));
mono_set_pending_exception (mono_get_exception_bad_image_format (""));
return NULL;
}
@ -1952,7 +1930,7 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad,
if (!ass) {
mono_image_close (image);
mono_raise_exception (mono_get_exception_bad_image_format (""));
mono_set_pending_exception (mono_get_exception_bad_image_format (""));
return NULL;
}
@ -1972,8 +1950,6 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef,
gchar *name;
gboolean parsed;
MONO_ARCH_SAVE_REGS;
g_assert (assRef != NULL);
name = mono_string_to_utf8 (assRef);
@ -1983,7 +1959,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef,
if (!parsed) {
/* This is a parse error... */
if (!refOnly)
refass = mono_try_assembly_resolve (domain, assRef, refOnly);
refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly);
return refass;
}
@ -1993,7 +1969,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef,
if (!ass) {
/* MS.NET doesn't seem to call the assembly resolve handler for refonly assemblies */
if (!refOnly)
refass = mono_try_assembly_resolve (domain, assRef, refOnly);
refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly);
else
refass = NULL;
if (!refass) {
@ -2013,15 +1989,14 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
{
MonoDomain * domain = mono_domain_get_by_id (domain_id);
MONO_ARCH_SAVE_REGS;
if (NULL == domain) {
MonoException *exc = mono_get_exception_execution_engine ("Failed to unload domain, domain id not found");
mono_raise_exception (exc);
mono_set_pending_exception (exc);
return;
}
if (domain == mono_get_root_domain ()) {
mono_raise_exception (mono_get_exception_cannot_unload_appdomain ("The default appdomain can not be unloaded."));
mono_set_pending_exception (mono_get_exception_cannot_unload_appdomain ("The default appdomain can not be unloaded."));
return;
}
@ -2053,19 +2028,18 @@ gint32
ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad,
MonoReflectionAssembly *refass, MonoArray *args)
{
MonoError error;
MonoImage *image;
MonoMethod *method;
MONO_ARCH_SAVE_REGS;
g_assert (refass);
image = refass->assembly->image;
g_assert (image);
method = mono_get_method (image, mono_image_get_entry_point (image), NULL);
method = mono_get_method_checked (image, mono_image_get_entry_point (image), NULL, NULL, &error);
if (!method)
g_error ("No entry point method found in %s", image->name);
g_error ("No entry point method found in %s due to %s", image->name, mono_error_get_message (&error));
if (!args)
args = (MonoArray *) mono_array_new (ad->data, mono_defaults.string_class, 0);
@ -2076,8 +2050,6 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad,
gint32
ves_icall_System_AppDomain_GetIDFromDomain (MonoAppDomain * ad)
{
MONO_ARCH_SAVE_REGS;
return ad->data->domain_id;
}
@ -2086,10 +2058,10 @@ ves_icall_System_AppDomain_InternalSetDomain (MonoAppDomain *ad)
{
MonoDomain *old_domain = mono_domain_get();
MONO_ARCH_SAVE_REGS;
if (!mono_domain_set (ad->data, FALSE))
mono_raise_exception (mono_get_exception_appdomain_unloaded ());
if (!mono_domain_set (ad->data, FALSE)) {
mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
return NULL;
}
return old_domain->domain;
}
@ -2100,10 +2072,10 @@ ves_icall_System_AppDomain_InternalSetDomainByID (gint32 domainid)
MonoDomain *current_domain = mono_domain_get ();
MonoDomain *domain = mono_domain_get_by_id (domainid);
MONO_ARCH_SAVE_REGS;
if (!domain || !mono_domain_set (domain, FALSE))
mono_raise_exception (mono_get_exception_appdomain_unloaded ());
if (!domain || !mono_domain_set (domain, FALSE)) {
mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
return NULL;
}
return current_domain->domain;
}
@ -2111,8 +2083,6 @@ ves_icall_System_AppDomain_InternalSetDomainByID (gint32 domainid)
void
ves_icall_System_AppDomain_InternalPushDomainRef (MonoAppDomain *ad)
{
MONO_ARCH_SAVE_REGS;
mono_thread_push_appdomain_ref (ad->data);
}
@ -2121,14 +2091,14 @@ ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id)
{
MonoDomain *domain = mono_domain_get_by_id (domain_id);
MONO_ARCH_SAVE_REGS;
if (!domain)
if (!domain) {
/*
* Raise an exception to prevent the managed code from executing a pop
* later.
*/
mono_raise_exception (mono_get_exception_appdomain_unloaded ());
mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
return;
}
mono_thread_push_appdomain_ref (domain);
}
@ -2136,24 +2106,18 @@ ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id)
void
ves_icall_System_AppDomain_InternalPopDomainRef (void)
{
MONO_ARCH_SAVE_REGS;
mono_thread_pop_appdomain_ref ();
}
MonoAppContext *
ves_icall_System_AppDomain_InternalGetContext ()
{
MONO_ARCH_SAVE_REGS;
return mono_context_get ();
}
MonoAppContext *
ves_icall_System_AppDomain_InternalGetDefaultContext ()
{
MONO_ARCH_SAVE_REGS;
return mono_domain_get ()->default_context;
}
@ -2162,8 +2126,6 @@ ves_icall_System_AppDomain_InternalSetContext (MonoAppContext *mc)
{
MonoAppContext *old_context = mono_context_get ();
MONO_ARCH_SAVE_REGS;
mono_context_set (mc);
return old_context;
@ -2321,7 +2283,7 @@ unload_thread_main (void *arg)
* class->runtime_info.
*/
mono_loader_lock ();
mono_loader_lock (); //FIXME why do we need the loader lock here?
mono_domain_lock (domain);
#ifdef HAVE_SGEN_GC
/*

View File

@ -183,7 +183,9 @@ static mono_mutex_t assembly_binding_mutex;
static GSList *loaded_assembly_bindings = NULL;
static MonoAssembly*
mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, gboolean refonly, gboolean postload);
mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, MonoAssembly *requesting, gboolean refonly, gboolean postload);
static MonoAssembly*
mono_assembly_load_full_internal (MonoAssemblyName *aname, MonoAssembly *requesting, const char *basedir, MonoImageOpenStatus *status, gboolean refonly);
static MonoBoolean
mono_assembly_is_in_gac (const gchar *filanem);
@ -1090,12 +1092,12 @@ mono_assembly_load_reference (MonoImage *image, int index)
if (image->assembly && image->assembly->ref_only) {
/* We use the loaded corlib */
if (!strcmp (aname.name, "mscorlib"))
reference = mono_assembly_load_full (&aname, image->assembly->basedir, &status, FALSE);
reference = mono_assembly_load_full_internal (&aname, image->assembly, image->assembly->basedir, &status, FALSE);
else {
reference = mono_assembly_loaded_full (&aname, TRUE);
if (!reference)
/* Try a postload search hook */
reference = mono_assembly_invoke_search_hook_internal (&aname, TRUE, TRUE);
reference = mono_assembly_invoke_search_hook_internal (&aname, image->assembly, TRUE, TRUE);
}
/*
@ -1111,9 +1113,9 @@ mono_assembly_load_reference (MonoImage *image, int index)
* The second load attempt has the basedir set to keep compatibility with the old mono behavior, for
* example bug-349190.2.cs and who knows how much more code in the wild.
*/
reference = mono_assembly_load (&aname, NULL, &status);
reference = mono_assembly_load_full_internal (&aname, image->assembly, NULL, &status, FALSE);
if (!reference && image->assembly)
reference = mono_assembly_load (&aname, image->assembly->basedir, &status);
reference = mono_assembly_load_full_internal (&aname, image->assembly, image->assembly->basedir, &status, FALSE);
}
if (reference == NULL){
@ -1232,13 +1234,36 @@ struct AssemblySearchHook {
AssemblySearchHook *assembly_search_hook = NULL;
static MonoAssembly*
mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, gboolean refonly, gboolean postload)
mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, MonoAssembly *requesting, gboolean refonly, gboolean postload)
{
AssemblySearchHook *hook;
for (hook = assembly_search_hook; hook; hook = hook->next) {
if ((hook->refonly == refonly) && (hook->postload == postload)) {
MonoAssembly *ass = hook->func (aname, hook->user_data);
MonoAssembly *ass;
/**
* A little explanation is in order here.
*
* The default postload search hook needs to know the requesting assembly to report it to managed code.
* The embedding API exposes a search hook that doesn't take such argument.
*
* The original fix would call the default search hook before all the registered ones and pass
* the requesting assembly to it. It works but broke a very suddle embedding API aspect that some users
* rely on. Which is the ordering between user hooks and the default runtime hook.
*
* Registering the hook after mono_jit_init would let your hook run before the default one and
* when using it to handle non standard app layouts this could save your app from a massive amount
* of syscalls that the default hook does when probing all sorts of places. Slow targets with horrible IO
* are all using this trick and if we broke this assumption they would be very disapointed at us.
*
* So what's the fix? We register the default hook using regular means and special case it when iterating
* over the registered hooks. This preserves ordering and enables managed resolve hooks to get the requesting
* assembly.
*/
if (hook->func == (void*)mono_domain_assembly_postload_search)
ass = mono_domain_assembly_postload_search (aname, requesting, refonly);
else
ass = hook->func (aname, hook->user_data);
if (ass)
return ass;
}
@ -1250,7 +1275,7 @@ mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, gboolean ref
MonoAssembly*
mono_assembly_invoke_search_hook (MonoAssemblyName *aname)
{
return mono_assembly_invoke_search_hook_internal (aname, FALSE, FALSE);
return mono_assembly_invoke_search_hook_internal (aname, NULL, FALSE, FALSE);
}
static void
@ -1764,7 +1789,7 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
* assemblies lock.
*/
if (ass->aname.name) {
ass2 = mono_assembly_invoke_search_hook_internal (&ass->aname, refonly, FALSE);
ass2 = mono_assembly_invoke_search_hook_internal (&ass->aname, NULL, refonly, FALSE);
if (ass2) {
g_free (ass);
g_free (base_dir);
@ -2367,7 +2392,7 @@ mono_assembly_load_with_partial_name (const char *name, MonoImageOpenStatus *sta
res->in_gac = TRUE;
else {
MonoDomain *domain = mono_domain_get ();
MonoReflectionAssembly *refasm = mono_try_assembly_resolve (domain, mono_string_new (domain, name), FALSE);
MonoReflectionAssembly *refasm = mono_try_assembly_resolve (domain, mono_string_new (domain, name), NULL, FALSE);
if (refasm)
res = refasm->assembly;
}
@ -2947,6 +2972,17 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
return result;
}
MonoAssembly*
mono_assembly_load_full_internal (MonoAssemblyName *aname, MonoAssembly *requesting, const char *basedir, MonoImageOpenStatus *status, gboolean refonly)
{
MonoAssembly *result = mono_assembly_load_full_nosearch (aname, basedir, status, refonly);
if (!result)
/* Try a postload search hook */
result = mono_assembly_invoke_search_hook_internal (aname, requesting, refonly, TRUE);
return result;
}
/**
* mono_assembly_load_full:
* @aname: A MonoAssemblyName with the assembly name to load.
@ -2966,12 +3002,7 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
MonoAssembly*
mono_assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status, gboolean refonly)
{
MonoAssembly *result = mono_assembly_load_full_nosearch (aname, basedir, status, refonly);
if (!result)
/* Try a postload search hook */
result = mono_assembly_invoke_search_hook_internal (aname, refonly, TRUE);
return result;
return mono_assembly_load_full_internal (aname, NULL, basedir, status, refonly);
}
/**
@ -2989,7 +3020,7 @@ mono_assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImage
MonoAssembly*
mono_assembly_load (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status)
{
return mono_assembly_load_full (aname, basedir, status, FALSE);
return mono_assembly_load_full_internal (aname, NULL, basedir, status, FALSE);
}
MonoAssembly*
@ -3000,7 +3031,7 @@ mono_assembly_loaded_full (MonoAssemblyName *aname, gboolean refonly)
aname = mono_assembly_remap_version (aname, &maped_aname);
res = mono_assembly_invoke_search_hook_internal (aname, refonly, FALSE);
res = mono_assembly_invoke_search_hook_internal (aname, NULL, refonly, FALSE);
return res;
}

View File

@ -30,6 +30,7 @@
#include <mono/utils/dtrace.h>
#include <mono/utils/gc_wrapper.h>
#include <mono/utils/mono-mutex.h>
#include <mono/utils/mono-counters.h>
#if HAVE_BOEHM_GC
@ -78,6 +79,8 @@ mono_gc_base_init (void)
if (gc_initialized)
return;
mono_counters_init ();
/*
* Handle the case when we are called from a thread different from the main thread,
* confusing libgc.
@ -744,16 +747,17 @@ create_allocator (int atype, int tls_key)
csig->params [0] = &mono_defaults.int_class->byval_arg;
csig->params [1] = &mono_defaults.int32_class->byval_arg;
} else {
csig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
csig->ret = &mono_defaults.object_class->byval_arg;
csig->params [0] = &mono_defaults.int_class->byval_arg;
csig->params [1] = &mono_defaults.int32_class->byval_arg;
}
mb = mono_mb_new (mono_defaults.object_class, "Alloc", MONO_WRAPPER_ALLOC);
bytes_var = mono_mb_add_local (mb, &mono_defaults.int32_class->byval_arg);
if (atype == ATYPE_STRING) {
/* a string alloator method takes the args: (vtable, len) */
/* bytes = (sizeof (MonoString) + ((len + 1) * 2)); */
/* bytes = (offsetof (MonoString, chars) + ((len + 1) * 2)); */
mono_mb_emit_ldarg (mb, 1);
mono_mb_emit_icon (mb, 1);
mono_mb_emit_byte (mb, MONO_CEE_ADD);
@ -764,15 +768,7 @@ create_allocator (int atype, int tls_key)
mono_mb_emit_byte (mb, MONO_CEE_ADD);
mono_mb_emit_stloc (mb, bytes_var);
} else {
/* bytes = vtable->klass->instance_size */
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoVTable, klass));
mono_mb_emit_byte (mb, MONO_CEE_ADD);
mono_mb_emit_byte (mb, MONO_CEE_LDIND_I);
mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoClass, instance_size));
mono_mb_emit_byte (mb, MONO_CEE_ADD);
/* FIXME: assert instance_size stays a 4 byte integer */
mono_mb_emit_byte (mb, MONO_CEE_LDIND_U4);
mono_mb_emit_ldarg (mb, 1);
mono_mb_emit_stloc (mb, bytes_var);
}
@ -958,7 +954,7 @@ mono_gc_is_critical_method (MonoMethod *method)
*/
MonoMethod*
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size)
{
int offset = -1;
int atype;
@ -1055,7 +1051,7 @@ mono_gc_is_critical_method (MonoMethod *method)
}
MonoMethod*
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size)
{
return NULL;
}
@ -1087,6 +1083,12 @@ mono_gc_get_write_barrier (void)
#endif
int
mono_gc_get_aligned_size_for_allocator (int size)
{
return size;
}
const char *
mono_gc_get_gc_name (void)
{

File diff suppressed because it is too large Load Diff

View File

@ -209,7 +209,9 @@ enum {
MONO_EXCEPTION_BAD_IMAGE = 12,
MONO_EXCEPTION_OBJECT_SUPPLIED = 13, /*The exception object is already created.*/
MONO_EXCEPTION_OUT_OF_MEMORY = 14,
MONO_EXCEPTION_INLINE_FAILED = 15
MONO_EXCEPTION_INLINE_FAILED = 15,
MONO_EXCEPTION_MONO_ERROR = 16,
/* add other exception type */
};
/* This struct collects the info needed for the runtime use of a class,
@ -559,7 +561,11 @@ struct _MonoDynamicGenericClass {
* A type parameter.
*/
struct _MonoGenericParam {
MonoGenericContainer *owner; /* Type or method this parameter was defined in. */
/*
* Type or method this parameter was defined in.
* If this is non-null, this is a MonoGenericParamFull structure.
*/
MonoGenericContainer *owner;
guint16 num;
/* For internal runtime use, used to make different versions of the same param */
guint16 serial;
@ -657,6 +663,8 @@ typedef struct {
gconstpointer trampoline;
MonoMethodSignature *sig;
const char *c_symbol;
MonoMethod *wrapper_method;
gboolean no_raise;
} MonoJitICallInfo;
typedef struct {
@ -1025,6 +1033,9 @@ mono_class_inflate_generic_method_full (MonoMethod *method, MonoClass *klass_hin
MonoMethod*
mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *klass_hint, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
MonoMethod *
mono_class_inflate_generic_method_checked (MonoMethod *method, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
MonoMethodInflated*
mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache) MONO_INTERNAL;
@ -1239,7 +1250,7 @@ MonoJitICallInfo *
mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save) MONO_INTERNAL;
MonoJitICallInfo *
mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, const char *c_symbol) MONO_INTERNAL;
mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol) MONO_INTERNAL;
void
mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper) MONO_INTERNAL;
@ -1394,4 +1405,10 @@ mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_toke
MonoClass *
mono_class_from_name_case_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error) MONO_INTERNAL;
MonoClassField*
mono_field_from_token_checked (MonoImage *image, uint32_t token, MonoClass **retklass, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
gpointer
mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
#endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */

View File

@ -72,10 +72,6 @@ static guint32 mono_field_resolve_flags (MonoClassField *field);
static void mono_class_setup_vtable_full (MonoClass *class, GList *in_setup);
static void mono_generic_class_setup_parent (MonoClass *klass, MonoClass *gklass);
void (*mono_debugger_class_init_func) (MonoClass *klass) = NULL;
/*
We use gclass recording to allow recursive system f types to be referenced by a parent.
@ -270,15 +266,21 @@ mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError
return NULL;
}
/* FIXME this leaks loader errors */
res = mono_class_from_name (image->references [idx - 1]->image, nspace, name);
done:
/* Generic case, should be avoided for when a better error is possible. */
if (!res && mono_error_ok (error)) {
if (mono_loader_get_last_error ()) { /*FIXME plug the above to not leak errors*/
mono_error_set_from_loader_error (error);
} else {
char *name = mono_class_name_from_token (image, type_token);
char *assembly = mono_assembly_name_from_token (image, type_token);
mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token);
}
}
g_assert (!mono_loader_get_last_error ());
return res;
}
@ -970,6 +972,12 @@ mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *conte
return mono_class_inflate_generic_method_full (method, NULL, context);
}
MonoMethod *
mono_class_inflate_generic_method_checked (MonoMethod *method, MonoGenericContext *context, MonoError *error)
{
return mono_class_inflate_generic_method_full_checked (method, NULL, context, error);
}
/**
* mono_class_inflate_generic_method_full:
*
@ -1082,10 +1090,8 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
iresult->context.class_inst = iresult->declaring->klass->generic_class->context.class_inst;
}
mono_loader_lock ();
cached = mono_method_inflated_lookup (iresult, FALSE);
if (cached) {
mono_loader_unlock ();
g_free (iresult);
return (MonoMethod*)cached;
}
@ -1156,12 +1162,9 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
* is_generic_method_definition().
*/
mono_method_inflated_lookup (iresult, TRUE);
mono_loader_unlock ();
return result;
return (MonoMethod*)mono_method_inflated_lookup (iresult, TRUE);
fail:
mono_loader_unlock ();
g_free (iresult);
return NULL;
}
@ -1241,7 +1244,7 @@ mono_method_get_generic_container (MonoMethod *method)
* mono_method_set_generic_container:
*
* Sets the generic container of METHOD to CONTAINER.
* LOCKING: Acquires the loader lock.
* LOCKING: Acquires the image lock.
*/
void
mono_method_set_generic_container (MonoMethod *method, MonoGenericContainer* container)
@ -1568,8 +1571,8 @@ mono_class_setup_fields (MonoClass *class)
explicit_size = mono_metadata_packing_from_typedef (class->image, class->type_token, &packing_size, &real_size);
if (explicit_size) {
if ((packing_size & 0xfffffff0) != 0) {
char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", class->name, packing_size);
if ((packing_size & 0xffffff00) != 0) {
char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", class->name, packing_size);
mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, err_msg);
return;
}
@ -2157,12 +2160,18 @@ mono_class_setup_methods (MonoClass *class)
MonoMethodSignature *sig;
int count_generic = 0, first_generic = 0;
int method_num = 0;
gboolean jagged_ctor = FALSE;
count = 3 + (class->rank > 1? 2: 1);
mono_class_setup_interfaces (class, &error);
g_assert (mono_error_ok (&error)); /*FIXME can this fail for array types?*/
if (class->rank == 1 && class->element_class->rank) {
jagged_ctor = TRUE;
class->method.count ++;
}
if (class->interface_count) {
count_generic = generic_array_methods (class);
first_generic = count;
@ -2191,6 +2200,19 @@ mono_class_setup_methods (MonoClass *class)
amethod = create_array_method (class, ".ctor", sig);
methods [method_num++] = amethod;
}
if (jagged_ctor) {
/* Jagged arrays have an extra ctor in .net which creates an array of arrays */
sig = mono_metadata_signature_alloc (class->image, class->rank + 1);
sig->ret = &mono_defaults.void_class->byval_arg;
sig->pinvoke = TRUE;
sig->hasthis = TRUE;
for (i = 0; i < class->rank + 1; ++i)
sig->params [i] = &mono_defaults.int32_class->byval_arg;
amethod = create_array_method (class, ".ctor", sig);
methods [method_num++] = amethod;
}
/* element Get (idx11, [idx2, ...]) */
sig = mono_metadata_signature_alloc (class->image, class->rank);
sig->ret = &class->element_class->byval_arg;
@ -2223,11 +2245,17 @@ mono_class_setup_methods (MonoClass *class)
for (i = 0; i < class->interface_count; i++)
setup_generic_array_ifaces (class, class->interfaces [i], methods, first_generic + i * count_generic);
} else {
MonoError error;
count = class->method.count;
methods = mono_class_alloc (class, sizeof (MonoMethod*) * count);
for (i = 0; i < count; ++i) {
int idx = mono_metadata_translate_token_index (class->image, MONO_TABLE_METHOD, class->method.first + i + 1);
methods [i] = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | idx, class);
methods [i] = mono_get_method_checked (class->image, MONO_TOKEN_METHOD_DEF | idx, class, NULL, &error);
if (!methods [i]) {
mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Could not load method %d due to %s", i, mono_error_get_message (&error)));
mono_error_cleanup (&error);
}
}
}
@ -2264,13 +2292,15 @@ mono_class_setup_methods (MonoClass *class)
MonoMethod*
mono_class_get_method_by_index (MonoClass *class, int index)
{
MonoError error;
/* Avoid calling setup_methods () if possible */
if (class->generic_class && !class->methods) {
MonoClass *gklass = class->generic_class->container_class;
MonoMethod *m;
m = mono_class_inflate_generic_method_full (
gklass->methods [index], class, mono_class_get_context (class));
m = mono_class_inflate_generic_method_full_checked (
gklass->methods [index], class, mono_class_get_context (class), &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
/*
* If setup_methods () is called later for this class, no duplicates are created,
* since inflate_generic_method guarantees that only one instance of a method
@ -2309,10 +2339,14 @@ mono_class_get_inflated_method (MonoClass *class, MonoMethod *method)
for (i = 0; i < gklass->method.count; ++i) {
if (gklass->methods [i] == method) {
if (class->methods)
if (class->methods) {
return class->methods [i];
else
return mono_class_inflate_generic_method_full (gklass->methods [i], class, mono_class_get_context (class));
} else {
MonoError error;
MonoMethod *result = mono_class_inflate_generic_method_full_checked (gklass->methods [i], class, mono_class_get_context (class), &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */
return result;
}
}
}
@ -2341,11 +2375,13 @@ mono_class_get_vtable_entry (MonoClass *class, int offset)
}
if (class->generic_class) {
MonoError error;
MonoClass *gklass = class->generic_class->container_class;
mono_class_setup_vtable (gklass);
m = gklass->vtable [offset];
m = mono_class_inflate_generic_method_full (m, class, mono_class_get_context (class));
m = mono_class_inflate_generic_method_full_checked (m, class, mono_class_get_context (class), &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */
} else {
mono_class_setup_vtable (class);
if (class->exception_type)
@ -2402,17 +2438,19 @@ mono_class_setup_properties (MonoClass *class)
properties = mono_class_new0 (class, MonoProperty, gklass->ext->property.count + 1);
for (i = 0; i < gklass->ext->property.count; i++) {
MonoError error;
MonoProperty *prop = &properties [i];
*prop = gklass->ext->properties [i];
if (prop->get)
prop->get = mono_class_inflate_generic_method_full (
prop->get, class, mono_class_get_context (class));
prop->get = mono_class_inflate_generic_method_full_checked (
prop->get, class, mono_class_get_context (class), &error);
if (prop->set)
prop->set = mono_class_inflate_generic_method_full (
prop->set, class, mono_class_get_context (class));
prop->set = mono_class_inflate_generic_method_full_checked (
prop->set, class, mono_class_get_context (class), &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
prop->parent = class;
}
@ -2441,11 +2479,14 @@ mono_class_setup_properties (MonoClass *class)
mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE);
if (class->image->uncompressed_metadata)
if (class->image->uncompressed_metadata) {
MonoError error;
/* It seems like the MONO_METHOD_SEMA_METHOD column needs no remapping */
method = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class);
else
method = mono_get_method_checked (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class, NULL, &error);
mono_error_cleanup (&error); /* FIXME don't swallow this error */
} else {
method = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
}
switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
case METHOD_SEMANTIC_SETTER:
@ -2494,8 +2535,11 @@ inflate_method_listz (MonoMethod **methods, MonoClass *class, MonoGenericContext
retval = g_new0 (MonoMethod*, count + 1);
count = 0;
for (om = methods, count = 0; *om; ++om, ++count)
retval [count] = mono_class_inflate_generic_method_full (*om, class, context);
for (om = methods, count = 0; *om; ++om, ++count) {
MonoError error;
retval [count] = mono_class_inflate_generic_method_full_checked (*om, class, context, &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
}
return retval;
}
@ -2533,14 +2577,21 @@ mono_class_setup_events (MonoClass *class)
context = mono_class_get_context (class);
for (i = 0; i < count; i++) {
MonoError error;
MonoEvent *event = &events [i];
MonoEvent *gevent = &gklass->ext->events [i];
mono_error_init (&error); //since we do conditional calls, we must ensure the default value is ok
event->parent = class;
event->name = gevent->name;
event->add = gevent->add ? mono_class_inflate_generic_method_full (gevent->add, class, context) : NULL;
event->remove = gevent->remove ? mono_class_inflate_generic_method_full (gevent->remove, class, context) : NULL;
event->raise = gevent->raise ? mono_class_inflate_generic_method_full (gevent->raise, class, context) : NULL;
event->add = gevent->add ? mono_class_inflate_generic_method_full_checked (gevent->add, class, context, &error) : NULL;
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
event->remove = gevent->remove ? mono_class_inflate_generic_method_full_checked (gevent->remove, class, context, &error) : NULL;
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
event->raise = gevent->raise ? mono_class_inflate_generic_method_full_checked (gevent->raise, class, context, &error) : NULL;
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
#ifndef MONO_SMALL_CONFIG
event->other = gevent->other ? inflate_method_listz (gevent->other, class, context) : NULL;
#endif
@ -2573,11 +2624,14 @@ mono_class_setup_events (MonoClass *class)
mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE);
if (class->image->uncompressed_metadata)
if (class->image->uncompressed_metadata) {
MonoError error;
/* It seems like the MONO_METHOD_SEMA_METHOD column needs no remapping */
method = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class);
else
method = mono_get_method_checked (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class, NULL, &error);
mono_error_cleanup (&error); /* FIXME don't swallow this error */
} else {
method = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
}
switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
case METHOD_SEMANTIC_ADD_ON:
@ -4914,10 +4968,12 @@ setup_generic_array_ifaces (MonoClass *class, MonoClass *iface, MonoMethod **met
//g_print ("setting up array interface: %s\n", mono_type_get_name_full (&iface->byval_arg, 0));
for (i = 0; i < generic_array_method_num; i++) {
MonoError error;
MonoMethod *m = generic_array_method_info [i].array_method;
MonoMethod *inflated;
inflated = mono_class_inflate_generic_method (m, &tmp_context);
inflated = mono_class_inflate_generic_method_checked (m, &tmp_context, &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
methods [pos++] = mono_marshal_get_generic_array_helper (class, iface, generic_array_method_info [i].name, inflated);
}
}
@ -5251,9 +5307,6 @@ mono_class_init (MonoClass *class)
mono_loader_unlock ();
if (mono_debugger_class_init_func)
mono_debugger_class_init_func (class);
return class->exception_type == MONO_EXCEPTION_NONE;
}
@ -5798,8 +5851,9 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
if (!class->enumtype) {
if (!mono_metadata_interfaces_from_typedef_full (
image, type_token, &interfaces, &icount, FALSE, context)){
mono_class_set_failure_from_loader_error (class, error, g_strdup ("Could not load interfaces"));
image, type_token, &interfaces, &icount, FALSE, context, error)){
mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup (mono_error_get_message (error)));
mono_loader_unlock ();
mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
return NULL;
@ -6118,8 +6172,11 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
#define FAST_CACHE_SIZE 16
/*
* LOCKING: Takes the image lock depending on @take_lock.
*/
static MonoClass *
get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_lock)
{
int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
MonoImage *image = param->image;
@ -6133,26 +6190,33 @@ get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
else
return image->var_cache_fast ? image->var_cache_fast [n] : NULL;
} else {
MonoClass *klass = NULL;
ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
if (ht) {
if (take_lock)
mono_image_lock (image);
klass = g_hash_table_lookup (ht, GINT_TO_POINTER (n));
if (take_lock)
mono_image_unlock (image);
}
return klass;
}
}
/*
* LOCKING: Acquires the loader lock.
* LOCKING: Image lock (param->image) must be held
*/
static void
set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
{
int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
MonoImage *image = param->image;
GHashTable *ht;
g_assert (image);
if (n < FAST_CACHE_SIZE) {
if (is_mvar) {
/* No locking needed */
/* Requires locking to avoid droping an already published class */
if (!image->mvar_cache_fast)
image->mvar_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
image->mvar_cache_fast [n] = klass;
@ -6161,11 +6225,9 @@ set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *kla
image->var_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
image->var_cache_fast [n] = klass;
}
return;
}
ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
} else {
GHashTable *ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
if (!ht) {
mono_image_lock (image);
ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
if (!ht) {
ht = g_hash_table_new (NULL, NULL);
@ -6175,40 +6237,30 @@ set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *kla
else
image->var_cache_slow = ht;
}
mono_image_unlock (image);
}
g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
}
}
/*
* LOCKING: Acquires the loader lock.
* LOCKING: Acquires the image lock (@image).
*/
MonoClass *
mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gboolean is_mvar)
{
MonoGenericContainer *container = mono_generic_param_owner (param);
MonoGenericParamInfo *pinfo;
MonoClass *klass;
mono_loader_lock ();
MonoGenericParamInfo *pinfo = NULL;
MonoClass *klass, *klass2;
if (container) {
pinfo = mono_generic_param_info (param);
if (pinfo->pklass) {
mono_loader_unlock ();
return pinfo->pklass;
}
klass = pinfo->pklass;
} else {
pinfo = NULL;
image = NULL;
klass = get_anon_gparam_class (param, is_mvar);
if (klass) {
mono_loader_unlock ();
klass = get_anon_gparam_class (param, is_mvar, TRUE);
}
if (klass)
return klass;
}
}
if (!image && container) {
if (is_mvar) {
@ -6226,14 +6278,29 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb
mono_memory_barrier ();
if (!image) //FIXME is this only needed by monodis? Can't we fix monodis instead of having this hack?
image = mono_defaults.corlib;
mono_image_lock (image);
if (container)
klass2 = pinfo->pklass;
else
klass2 = get_anon_gparam_class (param, is_mvar, FALSE);
if (klass2) {
klass = klass2;
} else {
if (container)
pinfo->pklass = klass;
else
set_anon_gparam_class (param, is_mvar, klass);
mono_loader_unlock ();
}
mono_image_unlock (image);
/* FIXME: Should this go inside 'make_generic_param_klass'? */
if (klass2)
mono_profiler_class_loaded (klass2, MONO_PROFILE_FAILED);
else
mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
return klass;
@ -6250,15 +6317,15 @@ mono_ptr_class_get (MonoType *type)
el_class = mono_class_from_mono_type (type);
image = el_class->image;
mono_loader_lock ();
if (!image->ptr_cache)
image->ptr_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
mono_image_lock (image);
if (image->ptr_cache) {
if ((result = g_hash_table_lookup (image->ptr_cache, el_class))) {
mono_loader_unlock ();
mono_image_unlock (image);
return result;
}
}
mono_image_unlock (image);
result = mono_image_alloc0 (image, sizeof (MonoClass));
classes_size += sizeof (MonoClass);
@ -6285,9 +6352,19 @@ mono_ptr_class_get (MonoType *type)
mono_class_setup_supertypes (result);
mono_image_lock (image);
if (image->ptr_cache) {
MonoClass *result2;
if ((result2 = g_hash_table_lookup (image->ptr_cache, el_class))) {
mono_image_unlock (image);
mono_profiler_class_loaded (result, MONO_PROFILE_FAILED);
return result2;
}
} else {
image->ptr_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
}
g_hash_table_insert (image->ptr_cache, el_class, result);
mono_loader_unlock ();
mono_image_unlock (image);
mono_profiler_class_loaded (result, MONO_PROFILE_OK);
@ -7191,10 +7268,7 @@ mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *c
if (class && context && mono_metadata_token_table (type_token) == MONO_TABLE_TYPESPEC)
class = mono_class_inflate_generic_class_checked (class, context, &error);
if (!class) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /*FIXME don't swallow this error */
}
g_assert (mono_error_ok (&error)); /* FIXME deprecate this function and forbit the runtime from using it. */
return class;
}
@ -7609,6 +7683,7 @@ search_modules (MonoImage *image, const char *name_space, const char *name)
MonoClass *
mono_class_from_name (MonoImage *image, const char* name_space, const char *name)
{
MonoError error;
GHashTable *nspace_table;
MonoImage *loaded_image;
guint32 token = 0;
@ -7710,7 +7785,11 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name
token = MONO_TOKEN_TYPE_DEF | token;
class = mono_class_get (image, token);
class = mono_class_get_checked (image, token, &error);
if (!mono_error_ok (&error)) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /* FIXME Don't swallow the error */
}
if (nested)
return return_nested_in (class, nested);
return class;
@ -8260,8 +8339,13 @@ mono_class_get_cctor (MonoClass *klass)
if (!klass->has_cctor)
return NULL;
if (mono_class_get_cached_class_info (klass, &cached_info))
return mono_get_method (klass->image, cached_info.cctor_token, klass);
if (mono_class_get_cached_class_info (klass, &cached_info)) {
MonoError error;
MonoMethod *result = mono_get_method_checked (klass->image, cached_info.cctor_token, klass, NULL, &error);
if (!mono_error_ok (&error))
g_error ("Could not lookup class cctor from cached metadata due to %s", mono_error_get_message (&error));
return result;
}
if (klass->generic_class && !klass->methods)
return mono_class_get_inflated_method (klass, mono_class_get_cctor (klass->generic_class->container_class));
@ -8285,9 +8369,13 @@ mono_class_get_finalizer (MonoClass *klass)
if (!mono_class_has_finalizer (klass))
return NULL;
if (mono_class_get_cached_class_info (klass, &cached_info))
return mono_get_method (cached_info.finalize_image, cached_info.finalize_token, NULL);
else {
if (mono_class_get_cached_class_info (klass, &cached_info)) {
MonoError error;
MonoMethod *result = mono_get_method_checked (cached_info.finalize_image, cached_info.finalize_token, NULL, NULL, &error);
if (!mono_error_ok (&error))
g_error ("Could not lookup finalizer from cached metadata due to %s", mono_error_get_message (&error));
return result;
}else {
mono_class_setup_vtable (klass);
return klass->vtable [finalize_slot];
}
@ -8391,6 +8479,18 @@ gpointer
mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class,
MonoGenericContext *context)
{
MonoError error;
gpointer res = mono_ldtoken_checked (image, token, handle_class, context, &error);
g_assert (mono_error_ok (&error));
return res;
}
gpointer
mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class,
MonoGenericContext *context, MonoError *error)
{
mono_error_init (error);
if (image_is_dynamic (image)) {
MonoClass *tmp_handle_class;
gpointer obj = mono_lookup_dynamic_token_class (image, token, TRUE, &tmp_handle_class, context);
@ -8409,43 +8509,42 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class,
case MONO_TOKEN_TYPE_DEF:
case MONO_TOKEN_TYPE_REF:
case MONO_TOKEN_TYPE_SPEC: {
MonoError error;
MonoType *type;
if (handle_class)
*handle_class = mono_defaults.typehandle_class;
type = mono_type_get_checked (image, token, context, &error);
if (!type) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /* FIXME Don't swallow the error */
type = mono_type_get_checked (image, token, context, error);
if (!type)
return NULL;
}
mono_class_init (mono_class_from_mono_type (type));
/* We return a MonoType* as handle */
return type;
}
case MONO_TOKEN_FIELD_DEF: {
MonoClass *class;
MonoError error;
guint32 type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token));
if (!type)
return NULL;
if (handle_class)
*handle_class = mono_defaults.fieldhandle_class;
class = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_DEF | type, context, &error);
if (!class) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /* FIXME Don't swallow the error */
if (!type) {
mono_error_set_bad_image (error, image, "Bad ldtoken %x", token);
return NULL;
}
if (handle_class)
*handle_class = mono_defaults.fieldhandle_class;
class = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_DEF | type, context, error);
if (!class)
return NULL;
mono_class_init (class);
return mono_class_get_field (class, token);
}
case MONO_TOKEN_METHOD_DEF:
case MONO_TOKEN_METHOD_SPEC: {
MonoMethod *meth;
meth = mono_get_method_full (image, token, NULL, context);
meth = mono_get_method_checked (image, token, NULL, context, error);
if (handle_class)
*handle_class = mono_defaults.methodhandle_class;
if (!meth)
return NULL;
return meth;
}
case MONO_TOKEN_MEMBER_REF: {
@ -8457,21 +8556,20 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class,
if (*sig == 0x6) { /* it's a field */
MonoClass *klass;
MonoClassField *field;
field = mono_field_from_token (image, token, &klass, context);
field = mono_field_from_token_checked (image, token, &klass, context, error);
if (handle_class)
*handle_class = mono_defaults.fieldhandle_class;
return field;
} else {
MonoMethod *meth;
meth = mono_get_method_full (image, token, NULL, context);
meth = mono_get_method_checked (image, token, NULL, context, error);
if (handle_class)
*handle_class = mono_defaults.methodhandle_class;
return meth;
}
}
default:
g_warning ("Unknown token 0x%08x in ldtoken", token);
break;
mono_error_set_bad_image (error, image, "Bad ldtoken %x", token);
}
return NULL;
}
@ -8895,7 +8993,10 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
}
if (i < klass->method.count) {
res = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass);
MonoError error;
res = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, &error);
mono_error_cleanup (&error); /* FIXME don't swallow the error */
/* Add 1 here so the if (*iter) check fails */
*iter = GUINT_TO_POINTER (i + 1);
return res;
@ -9447,6 +9548,7 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in
/* Search directly in the metadata to avoid calling setup_methods () */
for (i = 0; i < klass->method.count; ++i) {
MonoError error;
guint32 cols [MONO_METHOD_SIZE];
MonoMethod *method;
MonoMethodSignature *sig;
@ -9455,13 +9557,21 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in
mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, klass->method.first + i, cols, MONO_METHOD_SIZE);
if (!strcmp (mono_metadata_string_heap (klass->image, cols [MONO_METHOD_NAME]), name)) {
method = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass);
method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, &error);
if (!method) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
continue;
}
if (param_count == -1) {
res = method;
break;
}
sig = mono_method_signature (method);
if (sig && sig->param_count == param_count) {
sig = mono_method_signature_checked (method, &error);
if (!sig) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
continue;
}
if (sig->param_count == param_count) {
res = method;
break;
}
@ -9491,8 +9601,11 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p
if (klass->generic_class && !klass->methods) {
res = mono_class_get_method_from_name_flags (klass->generic_class->container_class, name, param_count, flags);
if (res)
res = mono_class_inflate_generic_method_full (res, klass, mono_class_get_context (klass));
if (res) {
MonoError error;
res = mono_class_inflate_generic_method_full_checked (res, klass, mono_class_get_context (klass), &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
}
return res;
}

View File

@ -524,8 +524,6 @@ cominterop_type_from_handle (MonoType *handle)
MonoDomain *domain = mono_domain_get ();
MonoClass *klass = mono_class_from_mono_type (handle);
MONO_ARCH_SAVE_REGS;
mono_class_init (klass);
return mono_type_get_object (domain, handle);
}
@ -1534,8 +1532,10 @@ ves_icall_System_Runtime_InteropServices_Marshal_GetCCW (MonoObject* object, Mon
g_assert (type->type);
klass = mono_type_get_class (type->type);
g_assert (klass);
if (!mono_class_init (klass))
mono_raise_exception (mono_class_get_exception_for_failure (klass));
if (!mono_class_init (klass)) {
mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
return NULL;
}
itf = cominterop_get_ccw (object, klass);
g_assert (itf);
@ -1588,8 +1588,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_ReleaseComObjectInternal (MonoO
guint32
ves_icall_System_Runtime_InteropServices_Marshal_GetComSlotForMethodInfoInternal (MonoReflectionMethod *m)
{
MONO_ARCH_SAVE_REGS;
#ifndef DISABLE_COM
return cominterop_get_com_slot_for_method (m->method);
#else
@ -1605,8 +1603,6 @@ ves_icall_System_ComObject_CreateRCW (MonoReflectionType *type)
MonoDomain *domain;
MonoObject *obj;
MONO_ARCH_SAVE_REGS;
domain = mono_object_domain (type);
klass = mono_class_from_mono_type (type->type);
@ -1693,8 +1689,10 @@ ves_icall_System_ComObject_GetInterfaceInternal (MonoComObject* obj, MonoReflect
{
#ifndef DISABLE_COM
MonoClass *class = mono_type_get_class (type->type);
if (!mono_class_init (class))
mono_raise_exception (mono_class_get_exception_for_failure (class));
if (!mono_class_init (class)) {
mono_set_pending_exception (mono_class_get_exception_for_failure (class));
return NULL;
}
return cominterop_get_interface (obj, class, (gboolean)throw_exception);
#else
@ -2097,13 +2095,14 @@ mono_marshal_free_ccw (MonoObject* object)
g_free (ccw_iter);
}
else
ccw_list_item = g_list_next(ccw_list_item);
ccw_list_item = g_list_next (ccw_list_item);
}
/* if list is empty remove original address from hash */
if (g_list_length (ccw_list) == 0)
g_hash_table_remove (ccw_hash, GINT_TO_POINTER (mono_object_hash (object)));
else if (ccw_list != ccw_list_orig)
g_hash_table_insert (ccw_hash, GINT_TO_POINTER (mono_object_hash (object)), ccw_list);
return TRUE;
}
@ -3308,23 +3307,17 @@ ves_icall_System_Runtime_InteropServices_Marshal_QueryInterfaceInternal (gpointe
MonoString *
ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
{
MONO_ARCH_SAVE_REGS;
return mono_string_from_bstr(ptr);
}
gpointer
ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR (MonoString* ptr)
{
MONO_ARCH_SAVE_REGS;
return mono_string_to_bstr(ptr);
}
void
ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
{
MONO_ARCH_SAVE_REGS;
mono_free_bstr (ptr);
}

View File

@ -29,8 +29,6 @@ mono_console_handle_async_ops (void)
MonoBoolean
ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
{
MONO_ARCH_SAVE_REGS;
return (GetFileType (handle) == FILE_TYPE_CHAR);
}

View File

@ -94,8 +94,6 @@ static struct termios initial_attr;
MonoBoolean
ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
{
MONO_ARCH_SAVE_REGS;
return isatty (GPOINTER_TO_INT (handle));
}
@ -106,8 +104,6 @@ set_property (gint property, gboolean value)
gboolean callset = FALSE;
gboolean check;
MONO_ARCH_SAVE_REGS;
if (tcgetattr (STDIN_FILENO, &attr) == -1)
return FALSE;
@ -152,8 +148,6 @@ ves_icall_System_ConsoleDriver_InternalKeyAvailable (gint32 timeout)
div_t divvy;
int ret, nbytes;
MONO_ARCH_SAVE_REGS;
do {
FD_ZERO (&rfds);
FD_SET (STDIN_FILENO, &rfds);
@ -208,8 +202,6 @@ tty_teardown (void)
{
int unused;
MONO_ARCH_SAVE_REGS;
if (!setup_finished)
return;
@ -281,7 +273,6 @@ static gboolean in_sigint;
MONO_SIG_HANDLER_FUNC (static, sigint_handler)
{
int save_errno;
MONO_ARCH_SAVE_REGS;
if (in_sigint)
return;
@ -449,8 +440,6 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardow
{
int dims;
MONO_ARCH_SAVE_REGS;
dims = terminal_get_dimensions ();
if (dims == -1){
int cols = 0, rows = 0;

View File

@ -46,8 +46,6 @@ ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
{
DWORD mode;
MONO_ARCH_SAVE_REGS;
return GetConsoleMode (handle, &mode) != 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -11,9 +11,10 @@
#define NUM_CALENDARS 4
#define NUM_SHORT_DATE_PATTERNS 14
#define NUM_LONG_DATE_PATTERNS 8
#define NUM_LONG_DATE_PATTERNS 10
#define NUM_SHORT_TIME_PATTERNS 12
#define NUM_LONG_TIME_PATTERNS 9
#define NUM_YEAR_MONTH_PATTERNS 8
#define idx2string(idx) (locale_strings + (idx))
@ -21,13 +22,7 @@
typedef guint16 stridx_t;
typedef struct {
const stridx_t long_date_pattern;
const stridx_t short_date_pattern;
const stridx_t long_time_pattern;
const stridx_t short_time_pattern;
const stridx_t year_month_pattern;
const stridx_t month_day_pattern;
const stridx_t am_designator;
const stridx_t pm_designator;
@ -49,6 +44,7 @@ typedef struct {
const stridx_t long_date_patterns [NUM_LONG_DATE_PATTERNS];
const stridx_t short_time_patterns [NUM_SHORT_TIME_PATTERNS];
const stridx_t long_time_patterns [NUM_LONG_TIME_PATTERNS];
const stridx_t year_month_patterns [NUM_YEAR_MONTH_PATTERNS];
} DateTimeFormatEntry;
typedef struct {

View File

@ -411,13 +411,12 @@ mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, uint32_t offset)
}
static void
add_line (StatementMachine *stm, GPtrArray *il_offset_array, GPtrArray *line_number_array, GPtrArray *source_file_array)
add_line (StatementMachine *stm, GPtrArray *il_offset_array, GPtrArray *line_number_array, GPtrArray *source_file_array, GPtrArray *hidden_array)
{
if (stm->line > 0) {
g_ptr_array_add (il_offset_array, GUINT_TO_POINTER (stm->offset));
g_ptr_array_add (line_number_array, GUINT_TO_POINTER (stm->line));
g_ptr_array_add (source_file_array, GUINT_TO_POINTER (stm->file));
}
g_ptr_array_add (hidden_array, GUINT_TO_POINTER (stm->is_hidden || stm->line <= 0));
if (!stm->is_hidden && !stm->first_file)
stm->first_file = stm->file;
@ -514,9 +513,9 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
MonoSymbolFile *symfile;
const unsigned char *ptr;
StatementMachine stm;
uint32_t i;
uint32_t i, j;
LineNumberTableFlags flags;
GPtrArray *il_offset_array, *line_number_array, *source_file_array;
GPtrArray *il_offset_array, *line_number_array, *source_file_array, *hidden_array;
gboolean has_column_info, has_end_info;
gboolean column_info_read = FALSE;
@ -549,6 +548,7 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
il_offset_array = g_ptr_array_new ();
line_number_array = g_ptr_array_new ();
source_file_array = g_ptr_array_new ();
hidden_array = g_ptr_array_new();
stm.line_base = read32 (&symfile->offset_table->_line_number_table_line_base);
stm.line_range = read32 (&symfile->offset_table->_line_number_table_line_range);
@ -596,7 +596,7 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
} else if (opcode < stm.opcode_base) {
switch (opcode) {
case DW_LNS_copy:
add_line (&stm, il_offset_array, line_number_array, source_file_array);
add_line (&stm, il_offset_array, line_number_array, source_file_array, hidden_array);
break;
case DW_LNS_advance_pc:
stm.offset += read_leb128 (ptr, &ptr);
@ -620,7 +620,7 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
stm.offset += opcode / stm.line_range;
stm.line += stm.line_base + (opcode % stm.line_range);
add_line (&stm, il_offset_array, line_number_array, source_file_array);
add_line (&stm, il_offset_array, line_number_array, source_file_array, hidden_array);
}
}
@ -662,32 +662,49 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
}
}
if (n_il_offsets)
if (n_il_offsets) {
*n_il_offsets = il_offset_array->len;
for (i = 0; i < il_offset_array->len; i++) {
if (GPOINTER_TO_UINT (g_ptr_array_index (hidden_array, i))) {
(*n_il_offsets)--;
}
}
}
if (il_offsets && line_numbers) {
*il_offsets = g_malloc (il_offset_array->len * sizeof (int));
*line_numbers = g_malloc (il_offset_array->len * sizeof (int));
*il_offsets = g_malloc (*n_il_offsets * sizeof (int));
*line_numbers = g_malloc (*n_il_offsets * sizeof (int));
j = 0;
for (i = 0; i < il_offset_array->len; ++i) {
(*il_offsets) [i] = GPOINTER_TO_UINT (g_ptr_array_index (il_offset_array, i));
(*line_numbers) [i] = GPOINTER_TO_UINT (g_ptr_array_index (line_number_array, i));
if (!GPOINTER_TO_UINT (g_ptr_array_index (hidden_array, i))) {
(*il_offsets)[j] = GPOINTER_TO_UINT (g_ptr_array_index (il_offset_array, i));
(*line_numbers)[j] = GPOINTER_TO_UINT (g_ptr_array_index (line_number_array, i));
j++;
}
}
}
if (column_numbers && has_column_info) {
column_info_read = TRUE;
*column_numbers = g_malloc (il_offset_array->len * sizeof (int));
for (i = 0; i < il_offset_array->len; ++i)
(*column_numbers) [i] = read_leb128 (ptr, &ptr);
*column_numbers = g_malloc (*n_il_offsets * sizeof (int));
j = 0;
for (i = 0; i < il_offset_array->len; ++i) {
int column = read_leb128 (ptr, &ptr);
if (!GPOINTER_TO_UINT (g_ptr_array_index (hidden_array, i))) {
(*column_numbers) [j] = column;
j++;
}
}
}
if (has_end_info && end_line_numbers) {
g_assert (end_column_numbers);
*end_line_numbers = g_malloc (il_offset_array->len * sizeof (int));
*end_column_numbers = g_malloc (il_offset_array->len * sizeof (int));
*end_line_numbers = g_malloc (*n_il_offsets * sizeof (int));
*end_column_numbers = g_malloc (*n_il_offsets * sizeof (int));
if (has_column_info && !column_info_read) {
for (i = 0; i < il_offset_array->len; ++i)
read_leb128 (ptr, &ptr);
}
j = 0;
for (i = 0; i < il_offset_array->len; ++i) {
int end_row, end_column = -1;
@ -695,14 +712,18 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
if (end_row != 0xffffff) {
end_row += GPOINTER_TO_UINT (g_ptr_array_index (line_number_array, i));
end_column = read_leb128 (ptr, &ptr);
(*end_line_numbers) [i] = end_row;
(*end_column_numbers) [i] = end_column;
if (!GPOINTER_TO_UINT (g_ptr_array_index (hidden_array, i))) {
(*end_line_numbers)[j] = end_row;
(*end_column_numbers)[j] = end_column;
j++;
}
}
}
}
g_ptr_array_free (il_offset_array, TRUE);
g_ptr_array_free (line_number_array, TRUE);
g_ptr_array_free (hidden_array, TRUE);
mono_debugger_unlock ();
return;

View File

@ -161,6 +161,9 @@ mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_f
MONO_API void
mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int *n_il_offsets, int **il_offsets, int **line_numbers, int **column_numbers, int **source_files, int **end_line_numbers, int **end_column_numbers);
gboolean
mono_debug_image_has_debug_info (MonoImage *image);
MONO_END_DECLS
#endif /* __MONO_SYMFILE_H__ */

3149
mta-mono/vendor/mono/metadata/decimal-ms.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
#ifndef __MONO_DECIMAL_MS_H__
#define __MONO_DECIMAL_MS_H__
typedef struct tagDECIMAL {
// Decimal.cs treats the first two shorts as one long
// And they seriable the data so we need to little endian
// seriliazation
// The wReserved overlaps with Variant's vt member
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
union {
struct {
uint8_t sign;
uint8_t scale;
} u;
uint16_t signscale;
} u;
uint16_t reserved;
#else
uint16_t reserved;
union {
struct {
uint8_t scale;
uint8_t sign;
} u;
uint16_t signscale;
} u;
#endif
uint32_t Hi32;
union {
struct {
uint32_t Lo32;
uint32_t Mid32;
} v;
uint64_t Lo64;
} v;
} MonoDecimal;
typedef enum {
MONO_DECIMAL_CMP_LT=-1,
MONO_DECIMAL_CMP_EQ,
MONO_DECIMAL_CMP_GT
} MonoDecimalCompareResult;
MonoDecimalCompareResult
mono_decimal_compare (MonoDecimal *left, MonoDecimal *right) MONO_INTERNAL;
void mono_decimal_init_single (MonoDecimal *_this, float value) MONO_INTERNAL;
void mono_decimal_init_double (MonoDecimal *_this, double value) MONO_INTERNAL;
void mono_decimal_floor (MonoDecimal *d) MONO_INTERNAL;
int32_t mono_decimal_get_hash_code (MonoDecimal *d) MONO_INTERNAL;
void mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2) MONO_INTERNAL;
void mono_decimal_round (MonoDecimal *d, int32_t decimals) MONO_INTERNAL;
void mono_decimal_tocurrency (MonoDecimal *decimal) MONO_INTERNAL;
double mono_decimal_to_double (MonoDecimal d) MONO_INTERNAL;
int32_t mono_decimal_to_int32 (MonoDecimal d) MONO_INTERNAL;
float mono_decimal_to_float (MonoDecimal d) MONO_INTERNAL;
void mono_decimal_truncate (MonoDecimal *d) MONO_INTERNAL;
void mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign);
void mono_decimal_divide (MonoDecimal *left, MonoDecimal *right);
int mono_decimal_from_number (void *from, MonoDecimal *target);
#endif

View File

@ -219,13 +219,11 @@ struct _MonoJitInfo {
gboolean has_arch_eh_info:1;
gboolean from_aot:1;
gboolean from_llvm:1;
gboolean dbg_hidden_inited:1;
gboolean dbg_attrs_inited:1;
gboolean dbg_hidden:1;
/* Whenever this jit info was loaded in async context */
gboolean async:1;
gboolean dbg_step_through_inited:1;
gboolean dbg_step_through:1;
gboolean dbg_non_user_code_inited:1;
gboolean dbg_non_user_code:1;
/* FIXME: Embed this after the structure later*/
@ -663,7 +661,10 @@ MONO_API void
mono_domain_add_class_static_data (MonoDomain *domain, MonoClass *klass, gpointer data, guint32 *bitmap);
MonoReflectionAssembly *
mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, gboolean refonly) MONO_INTERNAL;
mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly) MONO_INTERNAL;
MonoAssembly *
mono_domain_assembly_postload_search (MonoAssemblyName *aname, MonoAssembly *requesting, gboolean refonly) MONO_INTERNAL;
MonoAssembly* mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
const char *basedir,

View File

@ -119,8 +119,6 @@ static const MonoRuntimeInfo *current_runtime = NULL;
/* This is the list of runtime versions supported by this JIT.
*/
static const MonoRuntimeInfo supported_runtimes[] = {
{"v2.0.50215","2.0", { {2,0,0,0}, { 8,0,0,0}, {3,5,0,0}, {3,0,0,0} } },
{"v2.0.50727","2.0", { {2,0,0,0}, { 8,0,0,0}, {3,5,0,0}, {3,0,0,0} } },
{"v4.0.30319","4.5", { {4,0,0,0}, {10,0,0,0}, {4,0,0,0}, {4,0,0,0} } },
{"v4.0.30128","4.0", { {4,0,0,0}, {10,0,0,0}, {4,0,0,0}, {4,0,0,0} } },
{"v4.0.20506","4.0", { {4,0,0,0}, {10,0,0,0}, {4,0,0,0}, {4,0,0,0} } },
@ -130,7 +128,7 @@ static const MonoRuntimeInfo supported_runtimes[] = {
/* The stable runtime version */
#define DEFAULT_RUNTIME_VERSION "v2.0.50727"
#define DEFAULT_RUNTIME_VERSION "v4.0.30319"
/* Callbacks installed by the JIT */
static MonoCreateDomainFunc create_domain_hook;
@ -139,9 +137,6 @@ static MonoFreeDomainFunc free_domain_hook;
/* AOT cache configuration */
static MonoAotCacheConfig aot_cache_config;
/* This is intentionally not in the header file, so people don't misuse it. */
extern void _mono_debug_init_corlib (MonoDomain *domain);
static void
get_runtimes_from_exe (const char *exe_file, MonoImage **exe_image, const MonoRuntimeInfo** runtimes);
@ -512,6 +507,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters_init ();
#endif
mono_counters_init ();
mono_counters_register ("Max native code in a domain", MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_size);
mono_counters_register ("Max code space allocated in a domain", MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_alloc);
@ -835,8 +831,6 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
mono_defaults.customattribute_data_class = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
/* these are initialized lazily when COM features are used */
mono_class_init (mono_defaults.array_class);
mono_defaults.generic_nullable_class = mono_class_from_name (
mono_defaults.corlib, "System", "Nullable`1");
@ -847,8 +841,6 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
domain->friendly_name = g_path_get_basename (filename);
_mono_debug_init_corlib (domain);
return domain;
}

View File

@ -43,8 +43,6 @@ ves_icall_System_Environment_GetOSVersionString (void)
#ifdef HOST_WIN32
OSVERSIONINFOEX verinfo;
MONO_ARCH_SAVE_REGS;
verinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
if (GetVersionEx ((OSVERSIONINFO*)&verinfo)) {
char version [128];
@ -60,8 +58,6 @@ ves_icall_System_Environment_GetOSVersionString (void)
#elif defined(HAVE_SYS_UTSNAME_H)
struct utsname name;
MONO_ARCH_SAVE_REGS;
if (uname (&name) >= 0) {
return mono_string_new (mono_domain_get (), name.release);
}

View File

@ -775,12 +775,25 @@ mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions
MonoException *
mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception)
{
MonoRuntimeWrappedException *ex = (MonoRuntimeWrappedException*)
mono_exception_from_name (mono_get_corlib (), "System.Runtime.CompilerServices",
"RuntimeWrappedException");
MonoClass *klass;
MonoObject *o;
MonoMethod *method;
MonoDomain *domain = mono_domain_get ();
gpointer params [16];
MONO_OBJECT_SETREF (ex, wrapped_exception, wrapped_exception);
return (MonoException*)ex;
klass = mono_class_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
g_assert (klass);
o = mono_object_new (domain, klass);
g_assert (o != NULL);
method = mono_class_get_method_from_name (klass, ".ctor", 1);
g_assert (method);
params [0] = wrapped_exception;
mono_runtime_invoke (method, o, params, NULL);
return (MonoException *)o;
}
static gboolean

View File

@ -1,9 +1,6 @@
#ifndef _MONO_METADATA_EXCEPTION_H_
#define _MONO_METADATA_EXCEPTION_H_
/* here for compat: should not be used anymore */
#define MONO_ARCH_SAVE_REGS
#include <mono/metadata/object.h>
#include <mono/metadata/image.h>

View File

@ -270,8 +270,6 @@ ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=CreateDirectory (mono_string_chars (path), NULL);
@ -287,8 +285,6 @@ ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=RemoveDirectory (mono_string_chars (path));
@ -326,8 +322,6 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
gchar *utf8_path, *utf8_result, *full_name;
gint32 attributes;
MONO_ARCH_SAVE_REGS;
result = NULL;
*error = ERROR_SUCCESS;
@ -519,8 +513,6 @@ ves_icall_System_IO_MonoIO_GetCurrentDirectory (gint32 *error)
gunichar2 *buf;
int len, res_len;
MONO_ARCH_SAVE_REGS;
len = MAX_PATH + 1; /*FIXME this is too smal under most unix systems.*/
buf = g_new (gunichar2, len);
@ -555,8 +547,6 @@ ves_icall_System_IO_MonoIO_SetCurrentDirectory (MonoString *path,
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=SetCurrentDirectory (mono_string_chars (path));
@ -573,8 +563,6 @@ ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest,
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=MoveFile (mono_string_chars (path), mono_string_chars (dest));
@ -594,8 +582,6 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
MONO_ARCH_SAVE_REGS;
if (sourceFileName)
utf16_sourceFileName = mono_string_chars (sourceFileName);
if (destinationFileName)
@ -622,8 +608,6 @@ ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=CopyFile (mono_string_chars (path), mono_string_chars (dest), !overwrite);
@ -639,8 +623,6 @@ ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=DeleteFile (mono_string_chars (path));
@ -656,8 +638,6 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
{
gint32 ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=get_file_attributes (mono_string_chars (path));
@ -682,8 +662,6 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=SetFileAttributes (mono_string_chars (path),
@ -700,8 +678,6 @@ ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=GetFileType (handle);
@ -722,8 +698,6 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
gboolean result;
WIN32_FILE_ATTRIBUTE_DATA data;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
result = get_file_attributes_ex (mono_string_chars (path), &data);
@ -747,8 +721,6 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
int attributes, attrs;
gunichar2 *chars = mono_string_chars (filename);
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
if (options != 0){
@ -799,8 +771,6 @@ ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=CloseHandle (handle);
@ -820,14 +790,14 @@ ves_icall_System_IO_MonoIO_Read (HANDLE handle, MonoArray *dest,
gboolean result;
guint32 n;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
MONO_CHECK_ARG_NULL (dest);
MONO_CHECK_ARG_NULL (dest, 0);
if (dest_offset > mono_array_length (dest) - count)
mono_raise_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong."));
if (dest_offset > mono_array_length (dest) - count) {
mono_set_pending_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong."));
return 0;
}
buffer = mono_array_addr (dest, guchar, dest_offset);
result = ReadFile (handle, buffer, count, &n, NULL);
@ -849,14 +819,14 @@ ves_icall_System_IO_MonoIO_Write (HANDLE handle, MonoArray *src,
gboolean result;
guint32 n;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
MONO_CHECK_ARG_NULL (src);
MONO_CHECK_ARG_NULL (src, 0);
if (src_offset > mono_array_length (src) - count)
mono_raise_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong."));
if (src_offset > mono_array_length (src) - count) {
mono_set_pending_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong."));
return 0;
}
buffer = mono_array_addr (src, guchar, src_offset);
result = WriteFile (handle, buffer, count, &n, NULL);
@ -875,8 +845,6 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
{
gint32 offset_hi;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
offset_hi = offset >> 32;
@ -895,8 +863,6 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
{
gboolean ret;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
ret=FlushFileBuffers (handle);
@ -913,8 +879,6 @@ ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
gint64 length;
guint32 length_hi;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
length = GetFileSize (handle, &length_hi);
@ -934,8 +898,6 @@ ves_icall_System_IO_MonoIO_SetLength (HANDLE handle, gint64 length,
gint32 length_hi;
gboolean result;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
/* save file pointer */
@ -985,8 +947,6 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
const FILETIME *last_access_filetime;
const FILETIME *last_write_filetime;
MONO_ARCH_SAVE_REGS;
*error=ERROR_SUCCESS;
if (creation_time < 0)
@ -1015,24 +975,18 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
HANDLE
ves_icall_System_IO_MonoIO_get_ConsoleOutput ()
{
MONO_ARCH_SAVE_REGS;
return GetStdHandle (STD_OUTPUT_HANDLE);
}
HANDLE
ves_icall_System_IO_MonoIO_get_ConsoleInput ()
{
MONO_ARCH_SAVE_REGS;
return GetStdHandle (STD_INPUT_HANDLE);
}
HANDLE
ves_icall_System_IO_MonoIO_get_ConsoleError ()
{
MONO_ARCH_SAVE_REGS;
return GetStdHandle (STD_ERROR_HANDLE);
}
@ -1043,8 +997,6 @@ ves_icall_System_IO_MonoIO_CreatePipe (HANDLE *read_handle,
SECURITY_ATTRIBUTES attr;
gboolean ret;
MONO_ARCH_SAVE_REGS;
attr.nLength=sizeof(SECURITY_ATTRIBUTES);
attr.bInheritHandle=TRUE;
attr.lpSecurityDescriptor=NULL;
@ -1065,8 +1017,6 @@ MonoBoolean ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_ha
/* This is only used on Windows */
gboolean ret;
MONO_ARCH_SAVE_REGS;
ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
if(ret==FALSE) {
/* FIXME: throw an exception? */
@ -1147,8 +1097,6 @@ ves_icall_System_IO_MonoIO_get_InvalidPathChars ()
MonoDomain *domain;
int i, n;
MONO_ARCH_SAVE_REGS;
domain = mono_domain_get ();
n = sizeof (invalid_path_chars) / sizeof (gunichar2);
chars = mono_array_new (domain, mono_defaults.char_class, n);

View File

@ -81,10 +81,10 @@ enum {
MMAP_FILE_ACCESS_READ_WRITE_EXECUTE = 5,
};
#ifdef PLATFORM_ANDROID
#define DEFAULT_FILEMODE 0666
#else
#ifdef DEFFILEMODE
#define DEFAULT_FILEMODE DEFFILEMODE
#else
#define DEFAULT_FILEMODE 0666
#endif
static int mmap_init_state;
@ -280,9 +280,7 @@ open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int a
goto done;
}
*capacity = align_up_to_page_size ((size_t)*capacity);
if (*capacity > buf.st_size) {
if (result != 0 || *capacity > buf.st_size) {
int unused G_GNUC_UNUSED = ftruncate (fd, (off_t)*capacity);
}
@ -481,13 +479,15 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma
struct stat buf = { 0 };
fstat (fh->fd, &buf); //FIXME error handling
if (offset > buf.st_size || ((eff_size + offset) > buf.st_size && !is_special_zero_size_file (&buf)))
goto error;
/**
* We use the file size if one of the following conditions is true:
* -input size is zero
* -input size is bigger than the file and the file is not a magical zero size file such as /dev/mem.
*/
if (eff_size == 0 || (eff_size > buf.st_size && !is_special_zero_size_file (&buf)))
eff_size = buf.st_size;
if (eff_size == 0)
eff_size = align_up_to_page_size (buf.st_size) - offset;
*size = eff_size;
mmap_offset = align_down_to_page_size (offset);
@ -502,6 +502,7 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma
return 0;
}
error:
*mmap_handle = NULL;
*base_address = NULL;
return COULD_NOT_MAP_MEMORY;

View File

@ -54,8 +54,6 @@ ves_icall_System_IO_FSW_SupportsFSW (void)
void *iter;
char *err;
MONO_ARCH_SAVE_REGS;
inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
if (inotify_instance != -1) {
close (inotify_instance);
@ -104,8 +102,6 @@ ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
{
FAMEvent ev;
MONO_ARCH_SAVE_REGS;
if (FAMNextEvent (conn, &ev) == 1) {
*filename = mono_string_new (mono_domain_get (), ev.filename);
*code = ev.code;
@ -148,8 +144,6 @@ ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *name, gint32 ma
char *str, *path;
int retval;
MONO_ARCH_SAVE_REGS;
if (name == NULL)
return -1;

View File

@ -16,11 +16,11 @@
#include <mono/utils/gc_wrapper.h>
typedef struct {
int minor_gc_count;
int major_gc_count;
long long minor_gc_time;
long long major_gc_time;
long long major_gc_time_concurrent;
guint minor_gc_count;
guint major_gc_count;
guint64 minor_gc_time;
guint64 major_gc_time;
guint64 major_gc_time_concurrent;
} GCStats;
#define mono_domain_finalizers_lock(domain) mono_mutex_lock (&(domain)->finalizable_objects_hash_lock);
@ -220,7 +220,8 @@ typedef struct {
int alloc_type;
} AllocatorWrapperInfo;
MonoMethod* mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box) MONO_INTERNAL;
int mono_gc_get_aligned_size_for_allocator (int size) MONO_INTERNAL;
MonoMethod* mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size) MONO_INTERNAL;
MonoMethod* mono_gc_get_managed_array_allocator (MonoClass *klass) MONO_INTERNAL;
MonoMethod *mono_gc_get_managed_allocator_by_type (int atype) MONO_INTERNAL;
@ -369,7 +370,7 @@ typedef struct {
void (*object_queued_for_finalization) (MonoObject *object);
} MonoGCFinalizerCallbacks;
void mono_gc_register_finalizer_callbacks (MonoGCFinalizerCallbacks *callbacks);
MONO_API void mono_gc_register_finalizer_callbacks (MonoGCFinalizerCallbacks *callbacks);
#ifdef HOST_WIN32

View File

@ -415,8 +415,6 @@ ves_icall_System_GC_InternalCollect (int generation)
gint64
ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
{
MONO_ARCH_SAVE_REGS;
if (forceCollection)
mono_gc_collect (mono_gc_max_generation ());
return mono_gc_get_used_size ();
@ -425,8 +423,6 @@ ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
void
ves_icall_System_GC_KeepAlive (MonoObject *obj)
{
MONO_ARCH_SAVE_REGS;
/*
* Does nothing.
*/
@ -435,8 +431,7 @@ ves_icall_System_GC_KeepAlive (MonoObject *obj)
void
ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj)
{
if (!obj)
mono_raise_exception (mono_get_exception_argument_null ("obj"));
MONO_CHECK_ARG_NULL (obj,);
object_register_finalizer (obj, mono_gc_run_finalize);
}
@ -444,8 +439,7 @@ ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj)
void
ves_icall_System_GC_SuppressFinalize (MonoObject *obj)
{
if (!obj)
mono_raise_exception (mono_get_exception_argument_null ("obj"));
MONO_CHECK_ARG_NULL (obj,);
/* delegates have no finalizers, but we register them to deal with the
* unmanaged->managed trampoline. We don't let the user suppress it
@ -491,8 +485,10 @@ void
ves_icall_System_GC_register_ephemeron_array (MonoObject *array)
{
#ifdef HAVE_SGEN_GC
if (!mono_gc_ephemeron_array_add (array))
mono_raise_exception (mono_object_domain (array)->out_of_memory_ex);
if (!mono_gc_ephemeron_array_add (array)) {
mono_set_pending_exception (mono_object_domain (array)->out_of_memory_ex);
return;
}
#endif
}
@ -1070,6 +1066,7 @@ finalizer_thread (gpointer unused)
*/
g_assert (mono_domain_get () == mono_get_root_domain ());
mono_gc_set_skip_thread (TRUE);
if (wait) {
/* An alertable wait is required so this thread can be suspended on windows */
@ -1080,6 +1077,7 @@ finalizer_thread (gpointer unused)
#endif
}
wait = TRUE;
mono_gc_set_skip_thread (FALSE);
mono_threads_perform_thread_dump ();
@ -1149,12 +1147,11 @@ mono_gc_init (void)
MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_NORMAL].entries);
MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_PINNED].entries);
mono_counters_register ("Created object count", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &mono_stats.new_object_count);
mono_counters_register ("Minor GC collections", MONO_COUNTER_GC | MONO_COUNTER_INT, &gc_stats.minor_gc_count);
mono_counters_register ("Major GC collections", MONO_COUNTER_GC | MONO_COUNTER_INT, &gc_stats.major_gc_count);
mono_counters_register ("Minor GC time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.minor_gc_time);
mono_counters_register ("Major GC time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time);
mono_counters_register ("Major GC time concurrent", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time_concurrent);
mono_counters_register ("Minor GC collections", MONO_COUNTER_GC | MONO_COUNTER_UINT, &gc_stats.minor_gc_count);
mono_counters_register ("Major GC collections", MONO_COUNTER_GC | MONO_COUNTER_UINT, &gc_stats.major_gc_count);
mono_counters_register ("Minor GC time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &gc_stats.minor_gc_time);
mono_counters_register ("Major GC time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time);
mono_counters_register ("Major GC time concurrent", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time_concurrent);
mono_gc_base_init ();
@ -1224,7 +1221,7 @@ mono_gc_cleanup (void)
ret = WaitForSingleObjectEx (gc_thread->handle, INFINITE, TRUE);
g_assert (ret == WAIT_OBJECT_0);
mono_thread_join (MONO_UINT_TO_NATIVE_THREAD_ID (gc_thread->tid));
mono_thread_join (GUINT_TO_POINTER (gc_thread->tid));
}
}
gc_thread = NULL;

View File

@ -115,9 +115,6 @@ ICALL(BUFFER_2, "ByteLengthInternal", ves_icall_System_Buffer_ByteLengthInternal
ICALL(BUFFER_3, "GetByteInternal", ves_icall_System_Buffer_GetByteInternal)
ICALL(BUFFER_4, "SetByteInternal", ves_icall_System_Buffer_SetByteInternal)
ICALL_TYPE(CHAR, "System.Char", CHAR_1)
ICALL(CHAR_1, "GetDataTablePointers", ves_icall_System_Char_GetDataTablePointers)
ICALL_TYPE (COMPO_W, "System.ComponentModel.Win32Exception", COMPO_W_1)
ICALL (COMPO_W_1, "W32ErrorMessage", ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage)
@ -137,33 +134,27 @@ ICALL(CONSOLE_3, "SetBreak", ves_icall_System_ConsoleDriver_SetBreak )
ICALL(CONSOLE_4, "SetEcho", ves_icall_System_ConsoleDriver_SetEcho )
ICALL(CONSOLE_5, "TtySetup", ves_icall_System_ConsoleDriver_TtySetup )
ICALL_TYPE(CONVERT, "System.Convert", CONVERT_1)
ICALL(CONVERT_1, "InternalFromBase64CharArray", InternalFromBase64CharArray )
ICALL(CONVERT_2, "InternalFromBase64String", InternalFromBase64String )
ICALL_TYPE(TZONE, "System.CurrentSystemTimeZone", TZONE_1)
ICALL(TZONE_1, "GetTimeZoneData", ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData)
ICALL_TYPE(DTIME, "System.DateTime", DTIME_1)
ICALL(DTIME_1, "GetNow", mono_100ns_datetime)
ICALL(DTIME_2, "GetTimeMonotonic", mono_100ns_ticks)
ICALL(DTIME_1, "GetSystemTimeAsFileTime", mono_100ns_datetime)
#ifndef DISABLE_DECIMAL
ICALL_TYPE(DECIMAL, "System.Decimal", DECIMAL_1)
ICALL(DECIMAL_1, "decimal2Int64", mono_decimal2Int64)
ICALL(DECIMAL_2, "decimal2UInt64", mono_decimal2UInt64)
ICALL(DECIMAL_3, "decimal2double", mono_decimal2double)
//ICALL(DECIMAL_4, "decimal2string", mono_decimal2string)
ICALL(DECIMAL_5, "decimalCompare", mono_decimalCompare)
ICALL(DECIMAL_6, "decimalDiv", mono_decimalDiv)
ICALL(DECIMAL_7, "decimalFloorAndTrunc", mono_decimalFloorAndTrunc)
ICALL(DECIMAL_8, "decimalIncr", mono_decimalIncr)
ICALL(DECIMAL_9, "decimalIntDiv", mono_decimalIntDiv)
ICALL(DECIMAL_10, "decimalMult", mono_decimalMult)
ICALL(DECIMAL_11, "decimalRound", mono_decimalRound)
ICALL(DECIMAL_12, "decimalSetExponent", mono_decimalSetExponent)
ICALL(DECIMAL_13, "double2decimal", mono_double2decimal) /* FIXME: wrong signature. */
ICALL(DECIMAL_14, "string2decimal", mono_string2decimal)
ICALL(DECIMAL_1, ".ctor(double)", mono_decimal_init_double)
ICALL(DECIMAL_2, ".ctor(single)", mono_decimal_init_single)
ICALL(DECIMAL_3, "FCallAddSub(System.Decimal&,System.Decimal&,byte)", mono_decimal_addsub)
ICALL(DECIMAL_4, "FCallCompare", mono_decimal_compare)
ICALL(DECIMAL_5, "FCallDivide", mono_decimal_divide)
ICALL(DECIMAL_6, "FCallFloor", mono_decimal_floor)
ICALL(DECIMAL_7, "FCallMultiply", mono_decimal_multiply)
ICALL(DECIMAL_8, "FCallRound", mono_decimal_round)
ICALL(DECIMAL_9, "FCallToInt32", mono_decimal_to_int32)
ICALL(DECIMAL_10, "FCallTruncate", mono_decimal_truncate)
ICALL(DECIMAL_11, "GetHashCode", mono_decimal_get_hash_code)
ICALL(DECIMAL_12, "ToDouble", mono_decimal_to_double)
ICALL(DECIMAL_13, "ToSingle", mono_decimal_to_float)
#endif
ICALL_TYPE(DELEGATE, "System.Delegate", DELEGATE_1)
@ -231,12 +222,13 @@ ICALL(STOPWATCH_1, "GetTimestamp", mono_100ns_ticks)
ICALL_TYPE(DOUBLE, "System.Double", DOUBLE_1)
ICALL(DOUBLE_1, "ParseImpl", mono_double_ParseImpl)
ICALL_TYPE(ENUM, "System.Enum", ENUM_1)
ICALL_TYPE(ENUM, "System.Enum", ENUM_6)
ICALL(ENUM_6, "InternalHasFlag", ves_icall_System_Enum_InternalHasFlag)
ICALL(ENUM_1, "ToObject", ves_icall_System_Enum_ToObject)
ICALL(ENUM_5, "compare_value_to", ves_icall_System_Enum_compare_value_to)
ICALL(ENUM_4, "get_hashcode", ves_icall_System_Enum_get_hashcode)
ICALL(ENUM_3, "get_underlying_type", ves_icall_System_Enum_get_underlying_type)
ICALL(ENUM_2, "get_value", ves_icall_System_Enum_get_value)
ICALL(ENUM_2, "compare_value_to", ves_icall_System_Enum_compare_value_to)
ICALL(ENUM_3, "get_hashcode", ves_icall_System_Enum_get_hashcode)
ICALL(ENUM_4, "get_underlying_type", ves_icall_System_Enum_get_underlying_type)
ICALL(ENUM_5, "get_value", ves_icall_System_Enum_get_value)
ICALL_TYPE(ENV, "System.Environment", ENV_1)
ICALL(ENV_1, "Exit", ves_icall_System_Environment_Exit)
@ -276,6 +268,9 @@ ICALL(GC_7, "get_MaxGeneration", mono_gc_max_generation)
ICALL(GC_9, "get_ephemeron_tombstone", ves_icall_System_GC_get_ephemeron_tombstone)
ICALL(GC_8, "register_ephemeron_array", ves_icall_System_GC_register_ephemeron_array)
ICALL_TYPE(CALDATA, "System.Globalization.CalendarData", CALDATA_1)
ICALL(CALDATA_1, "fill_calendar_data", ves_icall_System_Globalization_CalendarData_fill_calendar_data)
ICALL_TYPE(COMPINF, "System.Globalization.CompareInfo", COMPINF_1)
ICALL(COMPINF_1, "assign_sortkey(object,string,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_assign_sortkey)
ICALL(COMPINF_2, "construct_compareinfo(string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo)
@ -284,8 +279,10 @@ ICALL(COMPINF_4, "internal_compare(string,int,int,string,int,int,System.Globaliz
ICALL(COMPINF_5, "internal_index(string,int,int,char,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index_char)
ICALL(COMPINF_6, "internal_index(string,int,int,string,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index)
ICALL_TYPE(CULINF, "System.Globalization.CultureInfo", CULINF_2)
ICALL(CULINF_2, "construct_datetime_format", ves_icall_System_Globalization_CultureInfo_construct_datetime_format)
ICALL_TYPE(CULDATA, "System.Globalization.CultureData", CULDATA_1)
ICALL(CULDATA_1, "fill_culture_data", ves_icall_System_Globalization_CultureData_fill_culture_data)
ICALL_TYPE(CULINF, "System.Globalization.CultureInfo", CULINF_5)
ICALL(CULINF_5, "construct_internal_locale_from_lcid", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid)
ICALL(CULINF_6, "construct_internal_locale_from_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name)
ICALL(CULINF_8, "construct_number_format", ves_icall_System_Globalization_CultureInfo_construct_number_format)
@ -297,6 +294,9 @@ ICALL_TYPE(REGINF, "System.Globalization.RegionInfo", REGINF_1)
ICALL(REGINF_1, "construct_internal_region_from_lcid", ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_lcid)
ICALL(REGINF_2, "construct_internal_region_from_name", ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_name)
ICALL_TYPE(TXTINF, "System.Globalization.TextInfo", TXTINF_1)
ICALL(TXTINF_1, "GetDataTablePointersLite", ves_icall_System_Globalization_TextInfo_GetDataTablePointersLite)
#ifndef PLATFORM_NO_DRIVEINFO
ICALL_TYPE(IODRIVEINFO, "System.IO.DriveInfo", IODRIVEINFO_1)
ICALL(IODRIVEINFO_1, "GetDiskFreeSpaceInternal", ves_icall_System_IO_DriveInfo_GetDiskFreeSpace)
@ -443,6 +443,11 @@ ICALL(NDNS_1, "GetHostByAddr_internal(string,string&,string[]&,string[]&)", ves_
ICALL(NDNS_2, "GetHostByName_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByName_internal)
ICALL(NDNS_3, "GetHostName_internal(string&)", ves_icall_System_Net_Dns_GetHostName_internal)
#if defined(PLATFORM_MACOSX) || defined(PLATFORM_BSD)
ICALL_TYPE(MAC_IFACE_PROPS, "System.Net.NetworkInformation.MacOsIPInterfaceProperties", MAC_IFACE_PROPS_1)
ICALL(MAC_IFACE_PROPS_1, "ParseRouteInfo_internal", ves_icall_System_Net_NetworkInformation_MacOsIPInterfaceProperties_ParseRouteInfo_internal)
#endif
ICALL_TYPE(SOCK, "System.Net.Sockets.Socket", SOCK_1)
ICALL(SOCK_1, "Accept_internal(intptr,int&,bool)", ves_icall_System_Net_Sockets_Socket_Accept_internal)
ICALL(SOCK_2, "Available_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Available_internal)
@ -476,6 +481,8 @@ ICALL_TYPE(SOCKEX, "System.Net.Sockets.SocketException", SOCKEX_1)
ICALL(SOCKEX_1, "WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal)
#endif /* !DISABLE_SOCKETS */
ICALL_TYPE(NUMBER, "System.Number", NUMBER_1)
ICALL(NUMBER_1, "NumberBufferToDecimal", mono_decimal_from_number)
ICALL_TYPE(NUMBER_FORMATTER, "System.NumberFormatter", NUMBER_FORMATTER_1)
ICALL(NUMBER_FORMATTER_1, "GetFormatterTables", ves_icall_System_NumberFormatter_GetFormatterTables)
@ -799,8 +806,8 @@ ICALL(STRING_10, "InternalIntern", ves_icall_System_String_InternalIntern)
ICALL(STRING_11, "InternalIsInterned", ves_icall_System_String_InternalIsInterned)
ICALL(STRING_12, "InternalSetLength", ves_icall_System_String_InternalSetLength)
ICALL_TYPE(TENC, "System.Text.Encoding", TENC_1)
ICALL(TENC_1, "InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage)
ICALL_TYPE(TENC, "System.Text.EncodingHelper", TENC_1)
ICALL(TENC_1, "InternalCodePage", ves_icall_System_Text_EncodingHelper_InternalCodePage)
ICALL_TYPE(ILOCK, "System.Threading.Interlocked", ILOCK_1)
ICALL(ILOCK_1, "Add(int&,int)", ves_icall_System_Threading_Interlocked_Add_Int)
@ -808,22 +815,23 @@ ICALL(ILOCK_2, "Add(long&,long)", ves_icall_System_Threading_Interlocked_Add_Lon
ICALL(ILOCK_3, "CompareExchange(T&,T,T)", ves_icall_System_Threading_Interlocked_CompareExchange_T)
ICALL(ILOCK_4, "CompareExchange(double&,double,double)", ves_icall_System_Threading_Interlocked_CompareExchange_Double)
ICALL(ILOCK_5, "CompareExchange(int&,int,int)", ves_icall_System_Threading_Interlocked_CompareExchange_Int)
ICALL(ILOCK_6, "CompareExchange(intptr&,intptr,intptr)", ves_icall_System_Threading_Interlocked_CompareExchange_IntPtr)
ICALL(ILOCK_7, "CompareExchange(long&,long,long)", ves_icall_System_Threading_Interlocked_CompareExchange_Long)
ICALL(ILOCK_8, "CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object)
ICALL(ILOCK_9, "CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single)
ICALL(ILOCK_10, "Decrement(int&)", ves_icall_System_Threading_Interlocked_Decrement_Int)
ICALL(ILOCK_11, "Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long)
ICALL(ILOCK_12, "Exchange(T&,T)", ves_icall_System_Threading_Interlocked_Exchange_T)
ICALL(ILOCK_13, "Exchange(double&,double)", ves_icall_System_Threading_Interlocked_Exchange_Double)
ICALL(ILOCK_14, "Exchange(int&,int)", ves_icall_System_Threading_Interlocked_Exchange_Int)
ICALL(ILOCK_15, "Exchange(intptr&,intptr)", ves_icall_System_Threading_Interlocked_Exchange_IntPtr)
ICALL(ILOCK_16, "Exchange(long&,long)", ves_icall_System_Threading_Interlocked_Exchange_Long)
ICALL(ILOCK_17, "Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object)
ICALL(ILOCK_18, "Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single)
ICALL(ILOCK_19, "Increment(int&)", ves_icall_System_Threading_Interlocked_Increment_Int)
ICALL(ILOCK_20, "Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long)
ICALL(ILOCK_21, "Read(long&)", ves_icall_System_Threading_Interlocked_Read_Long)
ICALL(ILOCK_6, "CompareExchange(int&,int,int,bool&)", ves_icall_System_Threading_Interlocked_CompareExchange_Int_Success)
ICALL(ILOCK_7, "CompareExchange(intptr&,intptr,intptr)", ves_icall_System_Threading_Interlocked_CompareExchange_IntPtr)
ICALL(ILOCK_8, "CompareExchange(long&,long,long)", ves_icall_System_Threading_Interlocked_CompareExchange_Long)
ICALL(ILOCK_9, "CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object)
ICALL(ILOCK_10, "CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single)
ICALL(ILOCK_11, "Decrement(int&)", ves_icall_System_Threading_Interlocked_Decrement_Int)
ICALL(ILOCK_12, "Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long)
ICALL(ILOCK_13, "Exchange(T&,T)", ves_icall_System_Threading_Interlocked_Exchange_T)
ICALL(ILOCK_14, "Exchange(double&,double)", ves_icall_System_Threading_Interlocked_Exchange_Double)
ICALL(ILOCK_15, "Exchange(int&,int)", ves_icall_System_Threading_Interlocked_Exchange_Int)
ICALL(ILOCK_16, "Exchange(intptr&,intptr)", ves_icall_System_Threading_Interlocked_Exchange_IntPtr)
ICALL(ILOCK_17, "Exchange(long&,long)", ves_icall_System_Threading_Interlocked_Exchange_Long)
ICALL(ILOCK_18, "Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object)
ICALL(ILOCK_19, "Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single)
ICALL(ILOCK_20, "Increment(int&)", ves_icall_System_Threading_Interlocked_Increment_Int)
ICALL(ILOCK_21, "Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long)
ICALL(ILOCK_22, "Read(long&)", ves_icall_System_Threading_Interlocked_Read_Long)
ICALL_TYPE(ITHREAD, "System.Threading.InternalThread", ITHREAD_1)
ICALL(ITHREAD_1, "Thread_free_internal", ves_icall_System_Threading_InternalThread_Thread_free_internal)
@ -869,6 +877,7 @@ ICALL(THREAD_4, "FreeLocalSlotValues", mono_thread_free_local_slot_values)
ICALL(THREAD_55, "GetAbortExceptionState", ves_icall_System_Threading_Thread_GetAbortExceptionState)
ICALL(THREAD_7, "GetDomainID", ves_icall_System_Threading_Thread_GetDomainID)
ICALL(THREAD_8, "GetName_internal(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetName_internal)
ICALL(THREAD_57, "GetPriority(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetPriority)
ICALL(THREAD_11, "GetState(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetState)
ICALL(THREAD_53, "Interrupt_internal(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_Interrupt_internal)
ICALL(THREAD_12, "Join_internal(System.Threading.InternalThread,int,intptr)", ves_icall_System_Threading_Thread_Join_internal)
@ -876,6 +885,7 @@ ICALL(THREAD_13, "MemoryBarrier", ves_icall_System_Threading_Thread_MemoryBarrie
ICALL(THREAD_14, "ResetAbort_internal()", ves_icall_System_Threading_Thread_ResetAbort)
ICALL(THREAD_15, "Resume_internal()", ves_icall_System_Threading_Thread_Resume)
ICALL(THREAD_18, "SetName_internal(System.Threading.InternalThread,string)", ves_icall_System_Threading_Thread_SetName_internal)
ICALL(THREAD_58, "SetPriority(System.Threading.InternalThread,int)", ves_icall_System_Threading_Thread_SetPriority)
ICALL(THREAD_21, "SetState(System.Threading.InternalThread,System.Threading.ThreadState)", ves_icall_System_Threading_Thread_SetState)
ICALL(THREAD_22, "Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal)
ICALL(THREAD_54, "SpinWait_nop", ves_icall_System_Threading_Thread_SpinWait_nop)
@ -919,6 +929,9 @@ ICALL(THREADP_35, "SetMaxThreads", ves_icall_System_Threading_ThreadPool_SetMaxT
ICALL(THREADP_4, "SetMinThreads", ves_icall_System_Threading_ThreadPool_SetMinThreads)
ICALL(THREADP_5, "pool_queue", icall_append_job)
ICALL_TYPE(TTIMER, "System.Threading.Timer", TTIMER_1)
ICALL(TTIMER_1, "GetTimeMonotonic", mono_100ns_ticks)
ICALL_TYPE(VOLATILE, "System.Threading.Volatile", VOLATILE_28)
ICALL(VOLATILE_28, "Read(T&)", ves_icall_System_Threading_Volatile_Read_T)
ICALL(VOLATILE_1, "Read(bool&)", ves_icall_System_Threading_Volatile_Read1)

File diff suppressed because it is too large Load Diff

View File

@ -1618,6 +1618,10 @@ mono_image_close_except_pools (MonoImage *image)
}
free_hash (image->native_wrapper_cache);
free_hash (image->native_wrapper_aot_cache);
free_hash (image->native_wrapper_check_cache);
free_hash (image->native_wrapper_aot_check_cache);
free_hash (image->native_func_wrapper_cache);
free_hash (image->managed_wrapper_cache);
free_hash (image->delegate_begin_invoke_cache);
free_hash (image->delegate_end_invoke_cache);
@ -1998,21 +2002,27 @@ mono_image_load_file_for_image (MonoImage *image, int fileidx)
if (fileidx < 1 || fileidx > t->rows)
return NULL;
mono_loader_lock ();
mono_image_lock (image);
if (image->files && image->files [fileidx - 1]) {
mono_loader_unlock ();
mono_image_unlock (image);
return image->files [fileidx - 1];
}
if (!image->files)
image->files = g_new0 (MonoImage*, t->rows);
fname_id = mono_metadata_decode_row_col (t, fileidx - 1, MONO_FILE_NAME);
fname = mono_metadata_string_heap (image, fname_id);
base_dir = g_path_get_dirname (image->name);
name = g_build_filename (base_dir, fname, NULL);
res = mono_image_open (name, NULL);
if (res) {
if (!res)
goto done;
mono_image_lock (image);
if (image->files && image->files [fileidx - 1]) {
MonoImage *old = res;
res = image->files [fileidx - 1];
mono_loader_unlock ();
mono_image_close (old);
} else {
int i;
/* g_print ("loaded file %s from %s (%p)\n", name, image->name, image->assembly); */
res->assembly = image->assembly;
@ -2021,13 +2031,18 @@ mono_image_load_file_for_image (MonoImage *image, int fileidx)
res->modules [i]->assembly = image->assembly;
}
if (!image->files)
image->files = g_new0 (MonoImage*, t->rows);
image->files [fileidx - 1] = res;
mono_loader_unlock ();
/* vtable fixup can't happen with the image lock held */
#ifdef HOST_WIN32
if (res->is_module_handle)
mono_image_fixup_vtable (res);
#endif
}
mono_loader_unlock ();
done:
g_free (name);
g_free (base_dir);
return res;

File diff suppressed because it is too large Load Diff

View File

@ -157,52 +157,72 @@ create_names_array_idx_dynamic (const guint16 *names, int ml)
return ret;
}
void
ves_icall_System_Globalization_CultureInfo_construct_datetime_format (MonoCultureInfo *this)
MonoBoolean
ves_icall_System_Globalization_CalendarData_fill_calendar_data (MonoCalendarData *this, MonoString *name, gint32 calendar_index)
{
MonoDomain *domain;
MonoDateTimeFormatInfo *datetime;
const DateTimeFormatEntry *dfe;
const CultureInfoNameEntry *ne;
const CultureInfoEntry *ci;
char *n;
MONO_ARCH_SAVE_REGS;
n = mono_string_to_utf8 (name);
ne = mono_binary_search (n, culture_name_entries, NUM_CULTURE_ENTRIES,
sizeof (CultureInfoNameEntry), culture_name_locator);
g_free (n);
if (ne == NULL) {
return FALSE;
}
g_assert (this->datetime_index >= 0);
datetime = this->datetime_format;
dfe = &datetime_format_entries [this->datetime_index];
ci = &culture_entries [ne->culture_entry_index];
dfe = &datetime_format_entries [ci->datetime_format_index];
domain = mono_domain_get ();
datetime->readOnly = this->is_read_only;
MONO_OBJECT_SETREF (datetime, AbbreviatedDayNames, create_names_array_idx (dfe->abbreviated_day_names,
NUM_DAYS));
MONO_OBJECT_SETREF (datetime, AbbreviatedMonthNames, create_names_array_idx (dfe->abbreviated_month_names,
NUM_MONTHS));
MONO_OBJECT_SETREF (datetime, AMDesignator, mono_string_new (domain, idx2string (dfe->am_designator)));
datetime->CalendarWeekRule = dfe->calendar_week_rule;
MONO_OBJECT_SETREF (datetime, DateSeparator, mono_string_new (domain, idx2string (dfe->date_separator)));
MONO_OBJECT_SETREF (datetime, DayNames, create_names_array_idx (dfe->day_names, NUM_DAYS));
MONO_OBJECT_SETREF (datetime, ShortestDayNames, create_names_array_idx (dfe->shortest_day_names, NUM_DAYS));
datetime->FirstDayOfWeek = dfe->first_day_of_week;
MONO_OBJECT_SETREF (datetime, LongDatePattern, mono_string_new (domain, idx2string (dfe->long_date_pattern)));
MONO_OBJECT_SETREF (datetime, LongTimePattern, mono_string_new (domain, idx2string (dfe->long_time_pattern)));
MONO_OBJECT_SETREF (datetime, MonthDayPattern, mono_string_new (domain, idx2string (dfe->month_day_pattern)));
MONO_OBJECT_SETREF (datetime, MonthNames, create_names_array_idx (dfe->month_names, NUM_MONTHS));
MONO_OBJECT_SETREF (datetime, PMDesignator, mono_string_new (domain, idx2string (dfe->pm_designator)));
MONO_OBJECT_SETREF (datetime, ShortDatePattern, mono_string_new (domain, idx2string (dfe->short_date_pattern)));
MONO_OBJECT_SETREF (datetime, ShortTimePattern, mono_string_new (domain, idx2string (dfe->short_time_pattern)));
MONO_OBJECT_SETREF (datetime, TimeSeparator, mono_string_new (domain, idx2string (dfe->time_separator)));
MONO_OBJECT_SETREF (datetime, YearMonthPattern, mono_string_new (domain, idx2string (dfe->year_month_pattern)));
MONO_OBJECT_SETREF (datetime, ShortDatePatterns, create_names_array_idx_dynamic (dfe->short_date_patterns,
MONO_OBJECT_SETREF (this, NativeName, mono_string_new (domain, idx2string (ci->nativename)));
MONO_OBJECT_SETREF (this, ShortDatePatterns, create_names_array_idx_dynamic (dfe->short_date_patterns,
NUM_SHORT_DATE_PATTERNS));
MONO_OBJECT_SETREF (datetime, LongDatePatterns, create_names_array_idx_dynamic (dfe->long_date_patterns,
MONO_OBJECT_SETREF (this, YearMonthPatterns, create_names_array_idx_dynamic (dfe->year_month_patterns,
NUM_YEAR_MONTH_PATTERNS));
MONO_OBJECT_SETREF (this, LongDatePatterns, create_names_array_idx_dynamic (dfe->long_date_patterns,
NUM_LONG_DATE_PATTERNS));
MONO_OBJECT_SETREF (datetime, ShortTimePatterns, create_names_array_idx_dynamic (dfe->short_time_patterns,
NUM_SHORT_TIME_PATTERNS));
MONO_OBJECT_SETREF (datetime, LongTimePatterns, create_names_array_idx_dynamic (dfe->long_time_patterns,
MONO_OBJECT_SETREF (this, MonthDayPattern, mono_string_new (domain, idx2string (dfe->month_day_pattern)));
MONO_OBJECT_SETREF (this, DayNames, create_names_array_idx (dfe->day_names, NUM_DAYS));
MONO_OBJECT_SETREF (this, AbbreviatedDayNames, create_names_array_idx (dfe->abbreviated_day_names,
NUM_DAYS));
MONO_OBJECT_SETREF (this, SuperShortDayNames, create_names_array_idx (dfe->shortest_day_names, NUM_DAYS));
MONO_OBJECT_SETREF (this, MonthNames, create_names_array_idx (dfe->month_names, NUM_MONTHS));
MONO_OBJECT_SETREF (this, AbbreviatedMonthNames, create_names_array_idx (dfe->abbreviated_month_names,
NUM_MONTHS));
MONO_OBJECT_SETREF (this, GenitiveMonthNames, create_names_array_idx (dfe->month_genitive_names, NUM_MONTHS));
MONO_OBJECT_SETREF (this, GenitiveAbbreviatedMonthNames, create_names_array_idx (dfe->abbreviated_month_genitive_names, NUM_MONTHS));
return TRUE;
}
void
ves_icall_System_Globalization_CultureData_fill_culture_data (MonoCultureData *this, gint32 datetime_index)
{
MonoDomain *domain;
const DateTimeFormatEntry *dfe;
g_assert (datetime_index >= 0);
dfe = &datetime_format_entries [datetime_index];
domain = mono_domain_get ();
MONO_OBJECT_SETREF (this, AMDesignator, mono_string_new (domain, idx2string (dfe->am_designator)));
MONO_OBJECT_SETREF (this, PMDesignator, mono_string_new (domain, idx2string (dfe->pm_designator)));
MONO_OBJECT_SETREF (this, TimeSeparator, mono_string_new (domain, idx2string (dfe->time_separator)));
MONO_OBJECT_SETREF (this, LongTimePatterns, create_names_array_idx_dynamic (dfe->long_time_patterns,
NUM_LONG_TIME_PATTERNS));
MONO_OBJECT_SETREF (datetime, GenitiveMonthNames, create_names_array_idx (dfe->month_genitive_names, NUM_MONTHS));
MONO_OBJECT_SETREF (datetime, GenitiveAbbreviatedMonthNames, create_names_array_idx (dfe->abbreviated_month_genitive_names, NUM_MONTHS));
MONO_OBJECT_SETREF (this, ShortTimePatterns, create_names_array_idx_dynamic (dfe->short_time_patterns,
NUM_SHORT_TIME_PATTERNS));
this->FirstDayOfWeek = dfe->first_day_of_week;
this->CalendarWeekRule = dfe->calendar_week_rule;
}
void
@ -212,8 +232,6 @@ ves_icall_System_Globalization_CultureInfo_construct_number_format (MonoCultureI
MonoNumberFormatInfo *number;
const NumberFormatEntry *nfe;
MONO_ARCH_SAVE_REGS;
g_assert (this->number_format != 0);
if (this->number_index < 0)
return;
@ -322,8 +340,6 @@ region_info_entry_from_lcid (int lcid)
const RegionInfoEntry *entry;
const CultureInfoEntry *ne;
MONO_ARCH_SAVE_REGS;
ne = mono_binary_search (&lcid, culture_entries, NUM_CULTURE_ENTRIES, sizeof (CultureInfoEntry), culture_lcid_locator);
if (ne == NULL)
@ -473,8 +489,6 @@ ves_icall_System_Globalization_CultureInfo_get_current_locale_name (void)
MonoString* ret;
MonoDomain *domain;
MONO_ARCH_SAVE_REGS;
locale = get_current_locale_name ();
if (locale == NULL)
return NULL;
@ -492,8 +506,6 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid (
{
const CultureInfoEntry *ci;
MONO_ARCH_SAVE_REGS;
ci = culture_info_entry_from_lcid (lcid);
if(ci == NULL)
return FALSE;
@ -508,8 +520,6 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name (
const CultureInfoNameEntry *ne;
char *n;
MONO_ARCH_SAVE_REGS;
n = mono_string_to_utf8 (name);
ne = mono_binary_search (n, culture_name_entries, NUM_CULTURE_ENTRIES,
sizeof (CultureInfoNameEntry), culture_name_locator);
@ -531,8 +541,6 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specif
gchar *locale;
gboolean ret;
MONO_ARCH_SAVE_REGS;
locale = mono_string_to_utf8 (name);
ret = construct_culture_from_specific_name (ci, locale);
g_free (locale);
@ -546,8 +554,6 @@ ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_lcid (M
{
const RegionInfoEntry *ri;
MONO_ARCH_SAVE_REGS;
ri = region_info_entry_from_lcid (lcid);
if(ri == NULL)
return FALSE;
@ -562,8 +568,6 @@ ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_name (M
const RegionInfoNameEntry *ne;
char *n;
MONO_ARCH_SAVE_REGS;
n = mono_string_to_utf8 (name);
ne = mono_binary_search (n, region_name_entries, NUM_REGION_ENTRIES,
sizeof (RegionInfoNameEntry), region_name_locator);
@ -590,8 +594,6 @@ ves_icall_System_Globalization_CultureInfo_internal_get_cultures (MonoBoolean ne
gint i, len;
gboolean is_neutral;
MONO_ARCH_SAVE_REGS;
domain = mono_domain_get ();
len = 0;
@ -641,8 +643,6 @@ void ves_icall_System_Globalization_CompareInfo_construct_compareinfo (MonoCompa
int ves_icall_System_Globalization_CompareInfo_internal_compare (MonoCompareInfo *this, MonoString *str1, gint32 off1, gint32 len1, MonoString *str2, gint32 off2, gint32 len2, gint32 options)
{
MONO_ARCH_SAVE_REGS;
/* Do a normal ascii string compare, as we only know the
* invariant locale if we dont have ICU
*/
@ -660,8 +660,6 @@ void ves_icall_System_Globalization_CompareInfo_assign_sortkey (MonoCompareInfo
MonoArray *arr;
gint32 keylen, i;
MONO_ARCH_SAVE_REGS;
keylen=mono_string_length (source);
arr=mono_array_new (mono_domain_get (), mono_get_byte_class (),
@ -675,31 +673,23 @@ void ves_icall_System_Globalization_CompareInfo_assign_sortkey (MonoCompareInfo
int ves_icall_System_Globalization_CompareInfo_internal_index (MonoCompareInfo *this, MonoString *source, gint32 sindex, gint32 count, MonoString *value, gint32 options, MonoBoolean first)
{
MONO_ARCH_SAVE_REGS;
return(string_invariant_indexof (source, sindex, count, value, first));
}
int ves_icall_System_Globalization_CompareInfo_internal_index_char (MonoCompareInfo *this, MonoString *source, gint32 sindex, gint32 count, gunichar2 value, gint32 options, MonoBoolean first)
{
MONO_ARCH_SAVE_REGS;
return(string_invariant_indexof_char (source, sindex, count, value,
first));
}
int ves_icall_System_Threading_Thread_current_lcid (void)
{
MONO_ARCH_SAVE_REGS;
/* Invariant */
return(0x007F);
}
MonoString *ves_icall_System_String_InternalReplace_Str_Comp (MonoString *this, MonoString *old, MonoString *new, MonoCompareInfo *comp)
{
MONO_ARCH_SAVE_REGS;
/* Do a normal ascii string compare and replace, as we only
* know the invariant locale if we dont have ICU
*/
@ -944,7 +934,8 @@ void load_normalization_resource (guint8 **argProps,
guint8 **argCombiningClass)
{
#ifdef DISABLE_NORMALIZATION
mono_raise_exception (mono_get_exception_not_supported ("This runtime has been compiled without string normalization support."));
mono_set_pending_exception (mono_get_exception_not_supported ("This runtime has been compiled without string normalization support."));
return;
#else
*argProps = (guint8*)props;
*argMappedChars = (guint8*) mappedChars;

View File

@ -26,12 +26,13 @@ typedef enum {
CompareOptions_Ordinal=0x40000000
} MonoCompareOptions;
extern MonoBoolean ves_icall_System_Globalization_CalendarData_fill_calendar_data (MonoCalendarData *this_obj, MonoString *name, gint32 calendar_index) MONO_INTERNAL;
extern void ves_icall_System_Globalization_CultureData_fill_culture_data (MonoCultureData *this_obj, gint32 datetime_index) MONO_INTERNAL;
extern void ves_icall_System_Globalization_CultureInfo_construct_internal_locale (MonoCultureInfo *this_obj, MonoString *locale) MONO_INTERNAL;
extern MonoString* ves_icall_System_Globalization_CultureInfo_get_current_locale_name (void) MONO_INTERNAL;
extern MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid (MonoCultureInfo *this_obj, gint lcid) MONO_INTERNAL;
extern MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name (MonoCultureInfo *this_obj, MonoString *name) MONO_INTERNAL;
extern MonoArray *ves_icall_System_Globalization_CultureInfo_internal_get_cultures (MonoBoolean neutral, MonoBoolean specific, MonoBoolean installed) MONO_INTERNAL;
extern void ves_icall_System_Globalization_CultureInfo_construct_datetime_format (MonoCultureInfo *this_obj) MONO_INTERNAL;
extern void ves_icall_System_Globalization_CultureInfo_construct_number_format (MonoCultureInfo *this_obj) MONO_INTERNAL;
extern void ves_icall_System_Globalization_CompareInfo_construct_compareinfo (MonoCompareInfo *comp, MonoString *locale) MONO_INTERNAL;
extern int ves_icall_System_Globalization_CompareInfo_internal_compare (MonoCompareInfo *this_obj, MonoString *str1, gint32 off1, gint32 len1, MonoString *str2, gint32 off2, gint32 len2, gint32 options) MONO_INTERNAL;

View File

@ -17,7 +17,9 @@ typedef enum {
DomainJitCodeHashLock,
IcallLock,
AssemblyBindingLock,
MarshalLock
MarshalLock,
ClassesLock,
LoaderGlobalDataLock
} RuntimeLocks;
#ifdef LOCK_TRACER

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@
#include <mono/metadata/opcodes.h>
#include <mono/metadata/reflection.h>
#include <mono/metadata/method-builder.h>
#include <mono/metadata/remoting.h>
#define mono_marshal_find_bitfield_offset(type, elem, byte_offset, bitmask) \
do { \
@ -289,6 +290,9 @@ mono_type_to_stind (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_method_from_wrapper (MonoMethod *wrapper) MONO_INTERNAL;
WrapperInfo*
mono_wrapper_info_create (MonoMethodBuilder *mb, WrapperSubtype subtype) MONO_INTERNAL;
void
mono_marshal_set_wrapper_info (MonoMethod *method, gpointer data) MONO_INTERNAL;
@ -392,6 +396,12 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) MONO_INTERNAL;
void
mono_marshal_free_inflated_wrappers (MonoMethod *method) MONO_INTERNAL;
void
mono_marshal_lock_internal (void) MONO_INTERNAL;
void
mono_marshal_unlock_internal (void) MONO_INTERNAL;
/* marshaling internal calls */
void *
@ -552,7 +562,7 @@ mono_marshal_find_nonzero_bit_offset (guint8 *buf, int len, int *byte_offset, gu
MonoMethodSignature*
mono_signature_no_pinvoke (MonoMethod *method) MONO_INTERNAL;
/* Called from cominterop.c */
/* Called from cominterop.c/remoting.c */
void
mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func, gboolean aot, gboolean check_exceptions, gboolean func_param) MONO_INTERNAL;
@ -573,46 +583,29 @@ mono_mb_create_and_cache (GHashTable *cache, gpointer key,
void
mono_marshal_emit_thread_interrupt_checkpoint (MonoMethodBuilder *mb) MONO_INTERNAL;
void
mono_marshal_emit_thread_force_interrupt_checkpoint (MonoMethodBuilder *mb) MONO_INTERNAL;
void
mono_marshal_use_aot_wrappers (gboolean use) MONO_INTERNAL;
MonoObject *
mono_marshal_xdomain_copy_value (MonoObject *val) MONO_INTERNAL;
int
mono_mb_emit_save_args (MonoMethodBuilder *mb, MonoMethodSignature *sig, gboolean save_this) MONO_INTERNAL;
#ifndef DISABLE_REMOTING
void
mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_remoting_invoke (MonoMethod *method) MONO_INTERNAL;
MonoMethod*
mono_mb_create (MonoMethodBuilder *mb, MonoMethodSignature *sig,
int max_stack, WrapperInfo *info) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_xappdomain_invoke (MonoMethod *method) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_remoting_invoke_for_target (MonoMethod *method, MonoRemotingTarget target_type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_stfld_wrapper (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_ldfld_wrapper (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_ldflda_wrapper (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_stfld_remote_wrapper (MonoClass *klass) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_proxy_cancast (MonoClass *klass) MONO_INTERNAL;
#endif
MonoMethod*
mono_mb_create_and_cache_full (GHashTable *cache, gpointer key,
MonoMethodBuilder *mb, MonoMethodSignature *sig,
int max_stack, WrapperInfo *info, gboolean *out_found) MONO_INTERNAL;
G_END_DECLS

View File

@ -29,6 +29,8 @@
*/
#define MEM_ALIGN 8
#define ALIGN_SIZE(s) (((s) + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1))
#define SIZEOF_MEM_POOL (ALIGN_SIZE (sizeof (MonoMemPool)))
#if MONO_SMALL_CONFIG
#define MONO_MEMPOOL_PAGESIZE 4096
@ -91,8 +93,8 @@ mono_mempool_new_size (int initial_size)
pool = g_malloc (initial_size);
pool->next = NULL;
pool->pos = (guint8*)pool + sizeof (MonoMemPool);
pool->end = pool->pos + initial_size - sizeof (MonoMemPool);
pool->pos = (guint8*)pool + SIZEOF_MEM_POOL;
pool->end = pool->pos + initial_size - SIZEOF_MEM_POOL;
pool->d.allocated = pool->size = initial_size;
total_bytes_allocated += initial_size;
return pool;
@ -165,8 +167,8 @@ mono_mempool_empty (MonoMemPool *pool)
pool->allocated = 0;
#else
pool->pos = (guint8*)pool + sizeof (MonoMemPool);
pool->end = pool->pos + pool->size - sizeof (MonoMemPool);
pool->pos = (guint8*)pool + SIZEOF_MEM_POOL;
pool->end = pool->pos + pool->size - SIZEOF_MEM_POOL;
#endif
}
@ -239,7 +241,7 @@ static int
get_next_size (MonoMemPool *pool, int size)
{
int target = pool->next? pool->next->size: pool->size;
size += sizeof (MonoMemPool);
size += SIZEOF_MEM_POOL;
/* increase the size */
target += target / 2;
while (target < size) {
@ -265,7 +267,7 @@ mono_mempool_alloc (MonoMemPool *pool, guint size)
{
gpointer rval;
size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
size = ALIGN_SIZE (size);
#ifdef MALLOC_ALLOCATION
{
@ -291,25 +293,25 @@ mono_mempool_alloc (MonoMemPool *pool, guint size)
if (G_UNLIKELY (pool->pos >= pool->end)) {
pool->pos -= size;
if (size >= 4096) {
MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
MonoMemPool *np = g_malloc (SIZEOF_MEM_POOL + size);
np->next = pool->next;
pool->next = np;
np->pos = (guint8*)np + sizeof (MonoMemPool);
np->size = sizeof (MonoMemPool) + size;
np->end = np->pos + np->size - sizeof (MonoMemPool);
pool->d.allocated += sizeof (MonoMemPool) + size;
total_bytes_allocated += sizeof (MonoMemPool) + size;
return (guint8*)np + sizeof (MonoMemPool);
np->pos = (guint8*)np + SIZEOF_MEM_POOL;
np->size = SIZEOF_MEM_POOL + size;
np->end = np->pos + np->size - SIZEOF_MEM_POOL;
pool->d.allocated += SIZEOF_MEM_POOL + size;
total_bytes_allocated += SIZEOF_MEM_POOL + size;
return (guint8*)np + SIZEOF_MEM_POOL;
} else {
int new_size = get_next_size (pool, size);
MonoMemPool *np = g_malloc (new_size);
np->next = pool->next;
pool->next = np;
pool->pos = (guint8*)np + sizeof (MonoMemPool);
np->pos = (guint8*)np + sizeof (MonoMemPool);
pool->pos = (guint8*)np + SIZEOF_MEM_POOL;
np->pos = (guint8*)np + SIZEOF_MEM_POOL;
np->size = new_size;
np->end = np->pos;
pool->end = pool->pos + new_size - sizeof (MonoMemPool);
pool->end = pool->pos + new_size - SIZEOF_MEM_POOL;
pool->d.allocated += new_size;
total_bytes_allocated += new_size;
@ -335,7 +337,7 @@ mono_mempool_alloc0 (MonoMemPool *pool, guint size)
#ifdef MALLOC_ALLOCATION
rval = mono_mempool_alloc (pool, size);
#else
size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
size = ALIGN_SIZE (size);
rval = pool->pos;
pool->pos = (guint8*)rval + size;

View File

@ -204,7 +204,7 @@ struct _MonoImage {
guint32 module_count;
gboolean *modules_loaded;
MonoImage **files;
MonoImage **files; /*protected by the image lock*/
gpointer aot_module;
@ -261,14 +261,12 @@ struct _MonoImage {
GHashTable *runtime_invoke_vtype_cache;
/*
* indexed by SignatureMethodPair
* indexed by SignaturePointerPair
*/
GHashTable *delegate_abstract_invoke_cache;
/*
* indexed by SignatureMethodPair
*/
GHashTable *delegate_bound_static_invoke_cache;
GHashTable *native_func_wrapper_cache;
/*
* indexed by MonoMethod pointers
*/
@ -277,6 +275,8 @@ struct _MonoImage {
GHashTable *managed_wrapper_cache;
GHashTable *native_wrapper_cache;
GHashTable *native_wrapper_aot_cache;
GHashTable *native_wrapper_check_cache;
GHashTable *native_wrapper_aot_check_cache;
GHashTable *native_func_wrapper_aot_cache;
GHashTable *remoting_invoke_cache;
GHashTable *synchronized_cache;
@ -647,7 +647,8 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *image,
MonoClass ***interfaces,
guint *count,
gboolean heap_alloc_result,
MonoGenericContext *context) MONO_INTERNAL;
MonoGenericContext *context,
MonoError *error) MONO_INTERNAL;
MonoArrayType *
mono_metadata_parse_array_full (MonoImage *image,
@ -673,7 +674,8 @@ mono_metadata_parse_method_signature_full (MonoImage *image,
MonoGenericContainer *generic_container,
int def,
const char *ptr,
const char **rptr);
const char **rptr,
MonoError *error);
MONO_API MonoMethodHeader *
mono_metadata_parse_mh_full (MonoImage *image,
@ -794,9 +796,10 @@ MonoException *mono_get_exception_field_access_msg (const char *msg) MONO_INTERN
MonoException *mono_get_exception_method_access_msg (const char *msg) MONO_INTERNAL;
MonoMethod* method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context) MONO_INTERNAL;
MonoMethod* method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
MonoMethod *mono_get_method_constrained_with_method (MonoImage *image, MonoMethod *method, MonoClass *constrained_class, MonoGenericContext *context) MONO_INTERNAL;
MonoMethod *mono_get_method_constrained_with_method (MonoImage *image, MonoMethod *method, MonoClass *constrained_class, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
MonoMethod *mono_get_method_constrained_checked (MonoImage *image, guint32 token, MonoClass *constrained_class, MonoGenericContext *context, MonoMethod **cil_method, MonoError *error) MONO_INTERNAL;
void mono_type_set_alignment (MonoTypeEnum type, int align) MONO_INTERNAL;
@ -804,5 +807,11 @@ MonoAotCacheConfig *mono_get_aot_cache_config (void) MONO_INTERNAL;
MonoType *
mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, MonoError *error) MONO_INTERNAL;
MonoMethodSignature*
mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
MonoMethod *
mono_get_method_checked (MonoImage *image, guint32 token, MonoClass *klass, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
#endif /* __MONO_METADATA_INTERNALS_H__ */

View File

@ -4296,19 +4296,13 @@ mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *e
mono_metadata_decode_row (table, row, data, MONO_METHODIMPL_SIZE);
body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL);
if (!body || mono_loader_get_last_error ()) {
mono_loader_clear_error ();
mono_error_set_bad_image (error, image, "Invalid methodimpl body for row %x", row);
body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL, error);
if (!body)
return FALSE;
}
declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL);
if (!declaration || mono_loader_get_last_error ()) {
mono_loader_clear_error ();
mono_error_set_bad_image (error, image, "Invalid methodimpl declaration for row %x", row);
declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL, error);
if (!declaration)
return FALSE;
}
/* FIXME
mono_class_setup_supertypes (class);

View File

@ -1761,6 +1761,8 @@ mono_metadata_get_param_attrs (MonoImage *m, int def, int param_count)
MonoMethodSignature*
mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 token)
{
MonoError error;
MonoMethodSignature *ret;
MonoTableInfo *tables = image->tables;
guint32 idx = mono_metadata_token_index (token);
guint32 sig;
@ -1776,7 +1778,12 @@ mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *gene
ptr = mono_metadata_blob_heap (image, sig);
mono_metadata_decode_blob_size (ptr, &ptr);
return mono_metadata_parse_method_signature_full (image, generic_container, 0, ptr, NULL);
ret = mono_metadata_parse_method_signature_full (image, generic_container, 0, ptr, NULL, &error);
if (!ret) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
}
return ret;
}
/*
@ -1893,7 +1900,7 @@ mono_metadata_signature_size (MonoMethodSignature *sig)
*/
MonoMethodSignature *
mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *container,
int def, const char *ptr, const char **rptr)
int def, const char *ptr, const char **rptr, MonoError *error)
{
MonoMethodSignature *method;
int i, *pattrs = NULL;
@ -1901,6 +1908,8 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
guint32 gen_param_count = 0;
gboolean is_open = FALSE;
mono_error_init (error);
if (*ptr & 0x10)
gen_param_count = 1;
if (*ptr & 0x20)
@ -1927,6 +1936,10 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
if (!method->ret) {
mono_metadata_free_method_signature (method);
g_free (pattrs);
if (mono_loader_get_last_error ())
mono_error_set_from_loader_error (error);
else
mono_error_set_bad_image (error, m, "Could not parse return type signature");
return NULL;
}
is_open = mono_class_is_open_constructed_type (method->ret);
@ -1935,12 +1948,14 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
for (i = 0; i < method->param_count; ++i) {
if (*ptr == MONO_TYPE_SENTINEL) {
if (method->call_convention != MONO_CALL_VARARG || def) {
g_warning ("found sentinel for methoddef or no vararg method 0x%08x on image %s", def, m->name);
g_assert (!mono_loader_get_last_error ());
mono_error_set_bad_image (error, m, "Found sentinel for methoddef or no vararg");
g_free (pattrs);
return NULL;
}
if (method->sentinelpos >= 0) {
g_warning ("found sentinel twice in the same signature for method 0x%08x on image %s", def, m->name);
g_assert (!mono_loader_get_last_error ());
mono_error_set_bad_image (error, m, "Found sentinel twice in the same signature.");
g_free (pattrs);
return NULL;
}
@ -1949,6 +1964,10 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
}
method->params [i] = mono_metadata_parse_type_full (m, container, MONO_PARSE_PARAM, pattrs ? pattrs [i+1] : 0, ptr, &ptr);
if (!method->params [i]) {
if (mono_loader_get_last_error ())
mono_error_set_from_loader_error (error);
else
mono_error_set_bad_image (error, m, "Could not parse type argument %d on method signature", i);
mono_metadata_free_method_signature (method);
g_free (pattrs);
return NULL;
@ -1974,6 +1993,7 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
* Add signature to a cache and increase ref count...
*/
g_assert (!mono_loader_get_last_error ());
return method;
}
@ -1994,7 +2014,14 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
MonoMethodSignature *
mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, const char **rptr)
{
return mono_metadata_parse_method_signature_full (m, NULL, def, ptr, rptr);
MonoError error;
MonoMethodSignature *ret;
ret = mono_metadata_parse_method_signature_full (m, NULL, def, ptr, rptr, &error);
if (!ret) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
}
return ret;
}
/*
@ -2735,9 +2762,6 @@ free_inflated_signature (MonoInflatedMethodSignature *sig)
g_free (sig);
}
/*
* LOCKING: assumes the loader lock is held.
*/
MonoMethodInflated*
mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache)
{
@ -2753,19 +2777,15 @@ mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache)
collect_data_free (&data);
if (cache) {
mono_image_set_lock (set);
g_hash_table_insert (set->gmethod_cache, method, method);
mono_image_set_unlock (set);
return method;
} else {
mono_image_set_lock (set);
res = g_hash_table_lookup (set->gmethod_cache, method);
mono_image_set_unlock (set);
return res;
if (!res && cache) {
g_hash_table_insert (set->gmethod_cache, method, method);
res = method;
}
mono_image_set_unlock (set);
return res;
}
/*
@ -3227,11 +3247,16 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer
if (!type->data.type)
return FALSE;
break;
case MONO_TYPE_FNPTR:
type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
if (!type->data.method)
case MONO_TYPE_FNPTR: {
MonoError error;
type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr, &error);
if (!type->data.method) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
return FALSE;
}
break;
}
case MONO_TYPE_ARRAY:
type->data.array = mono_metadata_parse_array_internal (m, container, transient, ptr, &ptr);
if (!type->data.array)
@ -4011,7 +4036,7 @@ mono_metadata_typedef_from_method (MonoImage *meta, guint32 index)
* Returns: TRUE on success, FALSE on failure.
*/
gboolean
mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context)
mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context, MonoError *error)
{
MonoTableInfo *tdef = &meta->tables [MONO_TABLE_INTERFACEIMPL];
locator_t loc;
@ -4022,6 +4047,8 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
*interfaces = NULL;
*count = 0;
mono_error_init (error);
if (!tdef->base)
return TRUE;
@ -4057,19 +4084,15 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
pos = start;
while (pos < tdef->rows) {
MonoError error;
MonoClass *iface;
mono_metadata_decode_row (tdef, pos, cols, MONO_INTERFACEIMPL_SIZE);
if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx)
break;
iface = mono_class_get_and_inflate_typespec_checked (
meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, &error);
if (iface == NULL) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /* FIXME Don't swallow the error */
meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, error);
if (iface == NULL)
return FALSE;
}
result [pos - start] = iface;
++pos;
}
@ -4095,10 +4118,12 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
MonoClass**
mono_metadata_interfaces_from_typedef (MonoImage *meta, guint32 index, guint *count)
{
MonoClass **interfaces;
MonoError error;
MonoClass **interfaces = NULL;
gboolean rv;
rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL);
rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL, &error);
g_assert (mono_error_ok (&error)); /* FIXME dont swallow the error */
if (rv)
return interfaces;
else
@ -5308,10 +5333,8 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec)
{
MonoError error;
MonoType *type = mono_type_create_from_typespec_checked (image, type_spec, &error);
if (!type) {
mono_loader_set_error_from_mono_error (&error);
mono_error_cleanup (&error); /* FIXME don't swallow error*/
}
if (!type)
g_error ("Could not create typespec %x due to %s", type_spec, mono_error_get_message (&error));
return type;
}
@ -5701,18 +5724,25 @@ mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
}
MonoMethod*
method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context)
method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context, MonoError *error)
{
MonoMethod *result = NULL;
guint32 idx = tok >> MONO_METHODDEFORREF_BITS;
mono_error_init (error);
switch (tok & MONO_METHODDEFORREF_MASK) {
case MONO_METHODDEFORREF_METHODDEF:
return mono_get_method_full (m, MONO_TOKEN_METHOD_DEF | idx, NULL, context);
result = mono_get_method_checked (m, MONO_TOKEN_METHOD_DEF | idx, NULL, context, error);
break;
case MONO_METHODDEFORREF_METHODREF:
return mono_get_method_full (m, MONO_TOKEN_MEMBER_REF | idx, NULL, context);
result = mono_get_method_checked (m, MONO_TOKEN_MEMBER_REF | idx, NULL, context, error);
break;
default:
mono_error_set_bad_image (error, m, "Invalid MethodDefOfRef token %x", tok);
}
g_assert_not_reached ();
return NULL;
return result;
}
/*
@ -5773,21 +5803,25 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod
MonoMethod *method;
if (!mono_verifier_verify_methodimpl_row (image, start + i, &error)) {
mono_error_cleanup (&error);
mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
break;
}
mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE);
method = method_from_method_def_or_ref (
image, cols [MONO_METHODIMPL_DECLARATION], generic_context);
if (method == NULL)
image, cols [MONO_METHODIMPL_DECLARATION], generic_context, &error);
if (method == NULL) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
}
result [i * 2] = method;
method = method_from_method_def_or_ref (
image, cols [MONO_METHODIMPL_BODY], generic_context);
if (method == NULL)
image, cols [MONO_METHODIMPL_BODY], generic_context, &error);
if (method == NULL) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
}
result [i * 2 + 1] = method;
}

File diff suppressed because it is too large Load Diff

View File

@ -17,14 +17,28 @@
G_BEGIN_DECLS
#define OWNER_MASK 0x0000ffff
#define ENTRY_COUNT_MASK 0xffff0000
#define ENTRY_COUNT_WAITERS 0x80000000
#define ENTRY_COUNT_ZERO 0x7fff0000
#define ENTRY_COUNT_SHIFT 16
struct _MonoThreadsSync
{
gsize owner; /* thread ID */
/*
* The entry count field can be negative, which would mean that the entry_sem is
* signaled and nobody is waiting to acquire it. This can happen when the thread
* that was waiting is either interrupted or timeouts, and the owner releases
* the lock before the forementioned thread updates the entry count.
*
* The 0 entry_count value is encoded as ENTRY_COUNT_ZERO, positive numbers being
* greater than it and negative numbers smaller than it.
*/
guint32 status; /* entry_count (16) | owner_id (16) */
guint32 nest;
#ifdef HAVE_MOVING_COLLECTOR
gint32 hash_code;
#endif
volatile gint32 entry_count;
HANDLE entry_sem;
GSList *wait_list;
void *data;
@ -38,11 +52,7 @@ void mono_monitor_cleanup (void) MONO_INTERNAL;
void** mono_monitor_get_object_monitor_weak_link (MonoObject *object) MONO_INTERNAL;
void mono_monitor_init_tls (void) MONO_INTERNAL;
MonoMethod* mono_monitor_get_fast_path (MonoMethod *enter_or_exit) MONO_INTERNAL;
void mono_monitor_threads_sync_members_offset (int *owner_offset, int *nest_offset, int *entry_count_offset) MONO_INTERNAL;
void mono_monitor_threads_sync_members_offset (int *status_offset, int *nest_offset) MONO_INTERNAL;
#define MONO_THREADS_SYNC_MEMBER_OFFSET(o) ((o)>>8)
#define MONO_THREADS_SYNC_MEMBER_SIZE(o) ((o)&0xff)
@ -54,9 +64,6 @@ extern void ves_icall_System_Threading_Monitor_Monitor_pulse_all(MonoObject *obj
extern gboolean ves_icall_System_Threading_Monitor_Monitor_wait(MonoObject *obj, guint32 ms) MONO_INTERNAL;
extern void ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject *obj, guint32 ms, char *lockTaken) MONO_INTERNAL;
gboolean
mono_monitor_is_il_fastpath_wrapper (MonoMethod *method) MONO_INTERNAL;
G_END_DECLS
#endif /* _MONO_METADATA_MONITOR_H_ */

View File

@ -20,10 +20,4 @@ void mono_debugger_unlock (void) MONO_INTERNAL
gchar *
mono_debugger_check_runtime_version (const char *filename) MONO_INTERNAL;
MonoDebugMethodAddressList *
mono_debugger_insert_method_breakpoint (MonoMethod *method, guint64 idx) MONO_INTERNAL;
int
mono_debugger_remove_method_breakpoint (guint64 index) MONO_INTERNAL;
#endif /* __MONO_DEBUG_DEBUGGER_H__ */

View File

@ -19,174 +19,79 @@
#include <mono/metadata/mono-debug-debugger.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/mempool.h>
#include <string.h>
#define DATA_TABLE_CHUNK_SIZE (16384-sizeof (MonoDebugDataChunk))
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
#if NO_UNALIGNED_ACCESS
#define RETURN_UNALIGNED(type, addr) \
{ \
type val; \
memcpy(&val, p + offset, sizeof(val)); \
return val; \
}
#define WRITE_UNALIGNED(type, addr, val) \
memcpy(addr, &val, sizeof(type))
#define READ_UNALIGNED(type, addr, val) \
memcpy(&val, addr, sizeof(type))
#else
#define RETURN_UNALIGNED(type, addr) \
return *(type*)(p + offset);
#define WRITE_UNALIGNED(type, addr, val) \
(*(type *)(addr) = (val))
#define READ_UNALIGNED(type, addr, val) \
val = (*(type *)(addr))
#endif
typedef enum {
MONO_DEBUG_DATA_ITEM_UNKNOWN = 0,
MONO_DEBUG_DATA_ITEM_CLASS,
MONO_DEBUG_DATA_ITEM_METHOD,
MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE
} MonoDebugDataItemType;
typedef struct _MonoDebugDataChunk MonoDebugDataChunk;
struct _MonoDebugDataChunk {
guint32 total_size;
guint32 allocated_size;
guint32 current_offset;
guint32 dummy;
MonoDebugDataChunk *next;
guint8 data [MONO_ZERO_LEN_ARRAY];
};
/* This contains per-domain info */
struct _MonoDebugDataTable {
gint32 domain;
gint32 _dummy; /* alignment for next field. */
MonoDebugDataChunk *first_chunk;
MonoDebugDataChunk *current_chunk;
GHashTable *method_hash;
MonoMemPool *mp;
GHashTable *method_address_hash;
};
typedef struct {
const gchar *method_name;
const gchar *obsolete_cil_code;
guint32 wrapper_type;
} MonoDebugWrapperData;
typedef struct {
guint32 size;
guint32 symfile_id;
guint32 domain_id;
guint32 method_id;
MonoDebugWrapperData *wrapper_data;
MonoMethod *method;
GSList *address_list;
} MonoDebugMethodHeader;
/* This contains JIT debugging information about a method in serialized format */
struct _MonoDebugMethodAddress {
MonoDebugMethodHeader header;
const guint8 *code_start;
const guint8 *wrapper_addr;
guint32 code_size;
guint8 data [MONO_ZERO_LEN_ARRAY];
};
struct _MonoDebugClassEntry {
guint32 size;
guint8 data [MONO_ZERO_LEN_ARRAY];
};
typedef struct {
gpointer code;
guint32 size;
} MonoDebugDelegateTrampolineEntry;
static MonoSymbolTable *mono_symbol_table = NULL;
static MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
static gint32 mono_debug_debugger_version = 5;
static gboolean mono_debug_initialized = FALSE;
static GHashTable *mono_debug_handles = NULL;
/* Maps MonoImage -> MonoMonoDebugHandle */
static GHashTable *mono_debug_handles;
/* Maps MonoDomain -> MonoDataTable */
static GHashTable *data_table_hash;
static GHashTable *data_table_hash = NULL;
static int next_symbol_file_id = 0;
static mono_mutex_t debugger_lock_mutex;
static int initialized = 0;
static gboolean is_attached = FALSE;
static MonoDebugHandle *mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size);
static MonoDebugHandle *_mono_debug_get_image (MonoImage *image);
static MonoDebugHandle *mono_debug_get_image (MonoImage *image);
static void mono_debug_add_assembly (MonoAssembly *assembly,
gpointer user_data);
static void mono_debug_add_type (MonoClass *klass);
static MonoDebugHandle *open_symfile_from_bundle (MonoImage *image);
void _mono_debug_init_corlib (MonoDomain *domain);
extern void (*mono_debugger_class_init_func) (MonoClass *klass);
static MonoDebugDataTable *
create_data_table (MonoDomain *domain)
{
MonoDebugDataTable *table;
MonoDebugDataChunk *chunk;
table = g_new0 (MonoDebugDataTable, 1);
table->domain = domain ? mono_domain_get_id (domain) : -1;
table->mp = mono_mempool_new ();
table->method_address_hash = g_hash_table_new (NULL, NULL);
table->method_hash = g_hash_table_new (NULL, NULL);
chunk = g_malloc0 (sizeof (MonoDebugDataChunk) + DATA_TABLE_CHUNK_SIZE);
chunk->total_size = DATA_TABLE_CHUNK_SIZE;
table->first_chunk = table->current_chunk = chunk;
if (domain) {
mono_debug_list_add (&mono_symbol_table->data_tables, table);
if (domain)
g_hash_table_insert (data_table_hash, domain, table);
}
return table;
}
static void
free_header_data (gpointer key, gpointer value, gpointer user_data)
{
MonoDebugMethodHeader *header = (MonoDebugMethodHeader*)value;
if (header->wrapper_data) {
g_free ((gpointer)header->wrapper_data->method_name);
g_free (header->wrapper_data);
}
g_slist_free (header->address_list);
}
static void
free_data_table (MonoDebugDataTable *table)
{
MonoDebugDataChunk *chunk, *next_chunk;
g_hash_table_foreach (table->method_hash, free_header_data, NULL);
g_hash_table_destroy (table->method_hash);
mono_mempool_destroy (table->mp);
g_hash_table_destroy (table->method_address_hash);
table->method_hash = NULL;
table->method_address_hash = NULL;
chunk = table->first_chunk;
while (chunk) {
next_chunk = chunk->next;
g_free (chunk);
chunk = next_chunk;
}
table->first_chunk = table->current_chunk = NULL;
mono_debug_list_remove (&mono_symbol_table->data_tables, table);
g_free (table);
}
@ -209,9 +114,7 @@ free_debug_handle (MonoDebugHandle *handle)
if (handle->symfile)
mono_debug_close_mono_symbol_file (handle->symfile);
/* decrease the refcount added with mono_image_addref () */
free_data_table (handle->type_table);
mono_image_close (handle->image);
g_free (handle->image_file);
g_free (handle);
}
@ -229,53 +132,24 @@ mono_debug_init (MonoDebugFormat format)
if (format == MONO_DEBUG_FORMAT_DEBUGGER)
g_error ("The mdb debugger is no longer supported.");
mono_debug_initialized = TRUE;
mono_debug_format = format;
/*
* This must be called before mono_debugger_initialize(), because the
* latter registers GC roots.
*/
mono_gc_base_init ();
mono_debugger_initialize ();
mono_debugger_lock ();
mono_symbol_table = g_new0 (MonoSymbolTable, 1);
mono_symbol_table->magic = MONO_DEBUGGER_MAGIC;
mono_symbol_table->version = MONO_DEBUGGER_MAJOR_VERSION;
mono_symbol_table->total_size = sizeof (MonoSymbolTable);
mono_debug_handles = g_hash_table_new_full
(NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
data_table_hash = g_hash_table_new_full (
NULL, NULL, NULL, (GDestroyNotify) free_data_table);
/* FIXME this is a disgusting hack. Kill it */
mono_debugger_class_init_func = mono_debug_add_type;
mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
mono_symbol_table->global_data_table = create_data_table (NULL);
mono_debugger_unlock ();
}
/*
* INTERNAL USE ONLY !
* FIXME this can have a decent name and exist in an internal header
*/
void
_mono_debug_init_corlib (MonoDomain *domain)
{
if (!mono_debug_initialized)
return;
mono_symbol_table->corlib = mono_debug_open_image (mono_defaults.corlib, NULL, 0);
}
void
mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
{
@ -296,14 +170,6 @@ mono_debug_cleanup (void)
g_hash_table_destroy (data_table_hash);
data_table_hash = NULL;
}
if (mono_symbol_table) {
if (mono_symbol_table->global_data_table)
free_data_table (mono_symbol_table->global_data_table);
g_free (mono_symbol_table);
mono_symbol_table = NULL;
}
}
void
@ -348,7 +214,7 @@ mono_debug_domain_unload (MonoDomain *domain)
* LOCKING: Assumes the debug lock is held.
*/
static MonoDebugHandle *
_mono_debug_get_image (MonoImage *image)
mono_debug_get_image (MonoImage *image)
{
return g_hash_table_lookup (mono_debug_handles, image);
}
@ -363,13 +229,12 @@ mono_debug_close_image (MonoImage *image)
mono_debugger_lock ();
handle = _mono_debug_get_image (image);
handle = mono_debug_get_image (image);
if (!handle) {
mono_debugger_unlock ();
return;
}
mono_debug_list_remove (&mono_symbol_table->symbol_files, handle);
g_hash_table_remove (mono_debug_handles, image);
mono_debugger_unlock ();
@ -385,26 +250,20 @@ mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
mono_debugger_lock ();
handle = _mono_debug_get_image (image);
handle = mono_debug_get_image (image);
if (handle != NULL) {
mono_debugger_unlock ();
return handle;
}
handle = g_new0 (MonoDebugHandle, 1);
handle->index = ++next_symbol_file_id;
handle->image = image;
mono_image_addref (image);
handle->image_file = g_strdup (mono_image_get_filename (image));
handle->type_table = create_data_table (NULL);
handle->symfile = mono_debug_open_mono_symbols (
handle, raw_contents, size, FALSE);
mono_debug_list_add (&mono_symbol_table->symbol_files, handle);
g_hash_table_insert (mono_debug_handles, image, handle);
mono_debugger_unlock ();
@ -426,51 +285,6 @@ mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
mono_debugger_unlock ();
}
static guint8 *
allocate_data_item (MonoDebugDataTable *table, MonoDebugDataItemType type, guint32 size)
{
guint32 chunk_size;
guint8 *data;
size = ALIGN_TO (size, sizeof (gpointer));
if (size + 16 < DATA_TABLE_CHUNK_SIZE)
chunk_size = DATA_TABLE_CHUNK_SIZE;
else
chunk_size = size + 16;
g_assert (table->current_chunk->current_offset == table->current_chunk->allocated_size);
if (table->current_chunk->allocated_size + size + 8 >= table->current_chunk->total_size) {
MonoDebugDataChunk *new_chunk;
new_chunk = g_malloc0 (sizeof (MonoDebugDataChunk) + chunk_size);
new_chunk->total_size = chunk_size;
table->current_chunk->next = new_chunk;
table->current_chunk = new_chunk;
}
data = &table->current_chunk->data [table->current_chunk->allocated_size];
table->current_chunk->allocated_size += size + 8;
* ((guint32 *) data) = size;
data += 4;
* ((guint32 *) data) = type;
data += 4;
return data;
}
static void
write_data_item (MonoDebugDataTable *table, const guint8 *data)
{
MonoDebugDataChunk *current_chunk = table->current_chunk;
guint32 size = * ((guint32 *) (data - 8));
g_assert (current_chunk->current_offset + size + 8 == current_chunk->allocated_size);
current_chunk->current_offset = current_chunk->allocated_size;
}
struct LookupMethodData
{
MonoDebugMethodInfo *minfo;
@ -491,7 +305,7 @@ lookup_method_func (gpointer key, gpointer value, gpointer user_data)
}
static MonoDebugMethodInfo *
_mono_debug_lookup_method (MonoMethod *method)
mono_debug_lookup_method_internal (MonoMethod *method)
{
struct LookupMethodData data;
@ -517,12 +331,51 @@ mono_debug_lookup_method (MonoMethod *method)
{
MonoDebugMethodInfo *minfo;
if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
return NULL;
mono_debugger_lock ();
minfo = _mono_debug_lookup_method (method);
minfo = mono_debug_lookup_method_internal (method);
mono_debugger_unlock ();
return minfo;
}
typedef struct
{
gboolean found;
MonoImage *image;
} LookupImageData;
static void
lookup_image_func (gpointer key, gpointer value, gpointer user_data)
{
MonoDebugHandle *handle = (MonoDebugHandle *) value;
LookupImageData *data = (LookupImageData *) user_data;
if (data->found)
return;
if (handle->image == data->image && handle->symfile)
data->found = TRUE;
}
gboolean
mono_debug_image_has_debug_info (MonoImage *image)
{
LookupImageData data;
if (!mono_debug_handles)
return FALSE;
memset (&data, 0, sizeof (data));
data.image = image;
mono_debugger_lock ();
g_hash_table_foreach (mono_debug_handles, lookup_image_func, &data);
mono_debugger_unlock ();
return data.found;
}
static inline void
write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
{
@ -572,31 +425,20 @@ write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
MonoDebugMethodAddress *
mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
{
MonoMethod *declaring;
MonoDebugDataTable *table;
MonoDebugMethodHeader *header;
MonoDebugMethodAddress *address;
MonoDebugMethodInfo *minfo;
MonoDebugHandle *handle;
guint8 buffer [BUFSIZ];
guint8 *ptr, *oldptr;
guint32 i, size, total_size, max_size;
gboolean is_wrapper = FALSE;
mono_debugger_lock ();
table = lookup_data_table (domain);
handle = _mono_debug_get_image (method->klass->image);
minfo = _mono_debug_lookup_method (method);
if (!minfo || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
(method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
(method->wrapper_type != MONO_WRAPPER_NONE)) {
is_wrapper = TRUE;
}
handle = mono_debug_get_image (method->klass->image);
minfo = mono_debug_lookup_method_internal (method);
max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
(25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
@ -642,16 +484,9 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
if (method_is_dynamic (method)) {
address = g_malloc0 (total_size);
} else {
address = (MonoDebugMethodAddress *) allocate_data_item (
table, MONO_DEBUG_DATA_ITEM_METHOD, total_size);
address = mono_mempool_alloc (table->mp, total_size);
}
address->header.size = total_size;
address->header.symfile_id = handle ? handle->index : 0;
address->header.domain_id = mono_domain_get_id (domain);
address->header.method_id = is_wrapper ? 0 : minfo->index;
address->header.method = method;
address->code_start = jit->code_start;
address->code_size = jit->code_size;
@ -659,32 +494,8 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
if (max_size > BUFSIZ)
g_free (oldptr);
declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
header = g_hash_table_lookup (table->method_hash, declaring);
if (!header) {
header = &address->header;
g_hash_table_insert (table->method_hash, declaring, header);
if (is_wrapper) {
MonoDebugWrapperData *wrapper;
header->wrapper_data = wrapper = g_new0 (MonoDebugWrapperData, 1);
wrapper->wrapper_type = method->wrapper_type;
wrapper->method_name = mono_method_full_name (declaring, TRUE);
wrapper->obsolete_cil_code = "";
}
} else {
address->header.wrapper_data = header->wrapper_data;
header->address_list = g_slist_prepend (header->address_list, address);
}
g_hash_table_insert (table->method_address_hash, method, address);
if (!method_is_dynamic (method))
write_data_item (table, (guint8 *) address);
mono_debugger_unlock ();
return address;
}
@ -692,9 +503,7 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
void
mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
{
MonoMethod *declaring;
MonoDebugDataTable *table;
MonoDebugMethodHeader *header;
MonoDebugMethodAddress *address;
if (!mono_debug_initialized)
@ -706,19 +515,9 @@ mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
table = lookup_data_table (domain);
declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
g_hash_table_remove (table->method_hash, declaring);
address = g_hash_table_lookup (table->method_address_hash, method);
if (address) {
header = &address->header;
if (header->wrapper_data) {
g_free ((char*)header->wrapper_data->method_name);
g_free (header->wrapper_data);
}
if (address)
g_free (address);
}
g_hash_table_remove (table->method_address_hash, method);
@ -728,22 +527,6 @@ mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
void
mono_debug_add_delegate_trampoline (gpointer code, int size)
{
MonoDebugDelegateTrampolineEntry *entry;
if (!mono_debug_initialized)
return;
mono_debugger_lock ();
entry = (MonoDebugDelegateTrampolineEntry *) allocate_data_item (
mono_symbol_table->global_data_table, MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE,
sizeof (MonoDebugDelegateTrampolineEntry));
entry->code = code;
entry->size = size;
write_data_item (mono_symbol_table->global_data_table, (guint8 *) entry);
mono_debugger_unlock ();
}
static inline guint32
@ -825,7 +608,6 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
jit = g_new0 (MonoDebugMethodJitInfo, 1);
jit->code_start = address->code_start;
jit->code_size = address->code_size;
jit->wrapper_addr = address->wrapper_addr;
ptr = (guint8 *) &address->data;
@ -866,63 +648,6 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
return jit;
}
static void
mono_debug_add_type (MonoClass *klass)
{
MonoDebugHandle *handle;
MonoDebugClassEntry *entry;
guint8 buffer [BUFSIZ];
guint8 *ptr, *oldptr;
guint32 size, total_size, max_size;
int base_offset = 0;
if (klass->generic_class || klass->rank ||
(klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR))
return;
mono_debugger_lock ();
handle = _mono_debug_get_image (klass->image);
if (!handle) {
mono_debugger_unlock ();
return;
}
max_size = 12 + sizeof (gpointer);
if (max_size > BUFSIZ)
ptr = oldptr = g_malloc (max_size);
else
ptr = oldptr = buffer;
if (klass->valuetype)
base_offset = - (int)(sizeof (MonoObject));
write_leb128 (klass->type_token, ptr, &ptr);
write_leb128 (klass->instance_size + base_offset, ptr, &ptr);
WRITE_UNALIGNED (gpointer, ptr, klass);
ptr += sizeof (gpointer);
size = ptr - oldptr;
g_assert (size < max_size);
total_size = size + sizeof (MonoDebugClassEntry);
g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE);
entry = (MonoDebugClassEntry *) allocate_data_item (
handle->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size);
entry->size = total_size;
memcpy (&entry->data, oldptr, size);
write_data_item (handle->type_table, (guint8 *) entry);
if (max_size > BUFSIZ)
g_free (oldptr);
mono_debugger_unlock ();
}
static MonoDebugMethodJitInfo *
find_method (MonoMethod *method, MonoDomain *domain)
{
@ -952,71 +677,11 @@ mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
return res;
}
struct LookupMethodAddressData
{
MonoMethod *method;
MonoDebugMethodHeader *result;
};
static void
lookup_method_address_func (gpointer key, gpointer value, gpointer user_data)
{
MonoDebugDataTable *table = (MonoDebugDataTable *) value;
struct LookupMethodAddressData *data = (struct LookupMethodAddressData *) user_data;
MonoDebugMethodHeader *header;
header = g_hash_table_lookup (table->method_hash, data->method);
if (header)
data->result = header;
}
MonoDebugMethodAddressList *
mono_debug_lookup_method_addresses (MonoMethod *method)
{
MonoDebugMethodAddressList *info;
MonoDebugMethodHeader *header = NULL;
struct LookupMethodAddressData data;
MonoMethod *declaring;
int count, size;
GSList *list;
guint8 *ptr;
g_assert ((mono_debug_debugger_version == 4) || (mono_debug_debugger_version == 5));
mono_debugger_lock ();
declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
data.method = declaring;
data.result = NULL;
g_hash_table_foreach (data_table_hash, lookup_method_address_func, &data);
header = data.result;
if (!header) {
mono_debugger_unlock ();
g_assert_not_reached ();
return NULL;
}
count = g_slist_length (header->address_list) + 1;
size = sizeof (MonoDebugMethodAddressList) + count * sizeof (gpointer);
info = g_malloc0 (size);
info->size = size;
info->count = count;
ptr = info->data;
WRITE_UNALIGNED (gpointer, ptr, header);
ptr += sizeof (gpointer);
for (list = header->address_list; list; list = list->next) {
WRITE_UNALIGNED (gpointer, ptr, list->data);
ptr += sizeof (gpointer);
}
mono_debugger_unlock ();
return info;
}
static gint32
@ -1085,7 +750,7 @@ mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDoma
return NULL;
mono_debugger_lock ();
minfo = _mono_debug_lookup_method (method);
minfo = mono_debug_lookup_method_internal (method);
if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
mono_debugger_unlock ();
return NULL;
@ -1118,7 +783,7 @@ mono_debug_lookup_locals (MonoMethod *method)
return NULL;
mono_debugger_lock ();
minfo = _mono_debug_lookup_method (method);
minfo = mono_debug_lookup_method_internal (method);
if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
mono_debugger_unlock ();
return NULL;
@ -1191,39 +856,6 @@ mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDom
return res;
}
void
mono_debug_list_add (MonoDebugList **list, gconstpointer data)
{
MonoDebugList *element, **ptr;
element = g_new0 (MonoDebugList, 1);
element->data = data;
for (ptr = list; *ptr; ptr = &(*ptr)->next)
;
*ptr = element;
}
void
mono_debug_list_remove (MonoDebugList **list, gconstpointer data)
{
MonoDebugList **ptr;
MonoDebugList *next;
for (ptr = list; *ptr; ptr = &(*ptr)->next) {
if ((*ptr)->data != data)
continue;
next = (*ptr)->next;
g_free ((*ptr));
*ptr = next;
break;
}
}
static gboolean is_attached = FALSE;
void
mono_set_is_debugger_attached (gboolean attached)
{
@ -1279,6 +911,27 @@ open_symfile_from_bundle (MonoImage *image)
return NULL;
}
void
mono_debugger_lock (void)
{
g_assert (initialized);
mono_mutex_lock (&debugger_lock_mutex);
}
void
mono_debugger_unlock (void)
{
g_assert (initialized);
mono_mutex_unlock (&debugger_lock_mutex);
}
void
mono_debugger_initialize ()
{
mono_mutex_init_recursive (&debugger_lock_mutex);
initialized = 1;
}
/**
* mono_debug_enabled:
*

View File

@ -149,9 +149,6 @@ struct _MonoDebugVarInfo {
#define MONO_DEBUGGER_MINOR_VERSION 6
#define MONO_DEBUGGER_MAGIC 0x7aff65af4253d427ULL
MONO_API void mono_debug_list_add (MonoDebugList **list, const void* data);
MONO_API void mono_debug_list_remove (MonoDebugList **list, const void* data);
MONO_API void mono_debug_init (MonoDebugFormat format);
MONO_API void mono_debug_open_image_from_memory (MonoImage *image, const mono_byte *raw_contents, int size);
MONO_API void mono_debug_cleanup (void);

View File

@ -28,6 +28,7 @@ PERFCTR_COUNTER(PROC_PBYTES, "Private Bytes", "", NumberOfItems64, unused)
PERFCTR_CAT(MONO_MEM, "Mono Memory", "", SingleInstance, Mono, MEM_NUM_OBJECTS)
PERFCTR_COUNTER(MEM_NUM_OBJECTS, "Allocated Objects", "", NumberOfItems64, unused)
PERFCTR_COUNTER(MEM_PHYS_TOTAL, "Total Physical Memory", "Physical memory installed in the machine, in bytes", NumberOfItems64, unused)
PERFCTR_COUNTER(MEM_PHYS_AVAILABLE, "Available Physical Memory", "Physical memory available in the machine, in bytes", NumberOfItems64, unused)
PERFCTR_CAT(ASPNET, "ASP.NET", "", MultiInstance, Mono, ASPNET_REQ_Q)
PERFCTR_COUNTER(ASPNET_REQ_Q, "Requests Queued", "", NumberOfItems64, aspnet_requests_queued)

View File

@ -25,6 +25,11 @@
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if defined (__APPLE__)
#include <mach/message.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#endif
#if defined (__NetBSD__) || defined (__APPLE__)
#include <sys/sysctl.h>
#endif
@ -224,6 +229,9 @@ typedef struct {
int num_instances;
/* variable length data follows */
char name [1];
// string name
// string help
// SharedCounter counters_info [num_counters]
} SharedCategory;
typedef struct {
@ -231,6 +239,7 @@ typedef struct {
unsigned int category_offset;
/* variable length data follows */
char instance_name [1];
// string name
} SharedInstance;
typedef struct {
@ -238,6 +247,8 @@ typedef struct {
guint8 seq_num;
/* variable length data follows */
char name [1];
// string name
// string help
} SharedCounter;
typedef struct {
@ -449,6 +460,76 @@ mono_determine_physical_ram_size (void)
#endif
}
static guint64
mono_determine_physical_ram_available_size (void)
{
#if defined (TARGET_WIN32)
MEMORYSTATUSEX memstat;
memstat.dwLength = sizeof (memstat);
GlobalMemoryStatusEx (&memstat);
return (guint64)memstat.ullAvailPhys;
#elif defined (__NetBSD__)
struct vmtotal vm_total;
guint64 page_size;
int mib [2];
size_t len;
mib = {
CTL_VM,
#if defined (VM_METER)
VM_METER
#else
VM_TOTAL
#endif
};
len = sizeof (vm_total);
sysctl (mib, 2, &vm_total, &len, NULL, 0);
mib = {
CTL_HW,
HW_PAGESIZE
};
len = sizeof (page_size);
sysctl (mib, 2, &page_size, &len, NULL, 0
return ((guint64) value.t_free * page_size) / 1024;
#elif defined (__APPLE__)
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
vm_statistics_data_t vmstat;
if (KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count)) {
g_warning ("Mono was unable to retrieve memory usage!");
return 0;
}
return (guint64) vmstat.free_count;
#elif defined (HAVE_SYSCONF)
guint64 page_size = 0, num_pages = 0;
/* sysconf works on most *NIX operating systems, if your system doesn't have it or if it
* reports invalid values, please add your OS specific code below. */
#ifdef _SC_PAGESIZE
page_size = (guint64)sysconf (_SC_PAGESIZE);
#endif
#ifdef _SC_AVPHYS_PAGES
num_pages = (guint64)sysconf (_SC_AVPHYS_PAGES);
#endif
if (!page_size || !num_pages) {
g_warning ("Your operating system's sysconf (3) function doesn't correctly report physical memory size!");
return 0;
}
return page_size * num_pages;
#else
return 0;
#endif
}
void
mono_perfcounters_init (void)
{
@ -478,9 +559,10 @@ perfctr_type_compress (int type)
return 2;
}
static unsigned char*
shared_data_find_room (int size)
static SharedHeader*
shared_data_reserve_room (int size, int ftype)
{
SharedHeader* header;
unsigned char *p = (unsigned char *)shared_area + shared_area->data_start;
unsigned char *end = (unsigned char *)shared_area + shared_area->size;
@ -490,7 +572,7 @@ shared_data_find_room (int size)
unsigned short *next;
if (*p == FTYPE_END) {
if (size < (end - p))
return p;
goto res;
return NULL;
}
if (p + 4 > end)
@ -499,12 +581,20 @@ shared_data_find_room (int size)
if (*p == FTYPE_DELETED) {
/* we reuse only if it's the same size */
if (*next == size) {
return p;
goto res;
}
}
p += *next;
}
return NULL;
res:
header = (SharedHeader*)p;
header->ftype = ftype;
header->extra = 0; /* data_offset could overflow here, so we leave this field unused */
header->size = size;
return header;
}
typedef gboolean (*SharedFunc) (SharedHeader *header, void *data);
@ -610,7 +700,8 @@ find_custom_counter (SharedCategory* cat, MonoString *name)
SharedCounter *counter = (SharedCounter*)p;
if (mono_string_compare_ascii (name, counter->name) == 0)
return counter;
p += 1 + strlen (p + 1) + 1; /* skip counter type and name */
p += 2; /* skip counter type */
p += strlen (p) + 1; /* skip counter name */
p += strlen (p) + 1; /* skip counter help */
}
return NULL;
@ -619,7 +710,7 @@ find_custom_counter (SharedCategory* cat, MonoString *name)
typedef struct {
unsigned int cat_offset;
SharedCategory* cat;
MonoString *instance;
char *name;
SharedInstance* result;
GSList *list;
} InstanceSearch;
@ -631,8 +722,8 @@ instance_search (SharedHeader *header, void *data)
if (header->ftype == FTYPE_INSTANCE) {
SharedInstance *ins = (SharedInstance*)header;
if (search->cat_offset == ins->category_offset) {
if (search->instance) {
if (mono_string_compare_ascii (search->instance, ins->instance_name) == 0) {
if (search->name) {
if (strcmp (search->name, ins->instance_name) == 0) {
search->result = ins;
return FALSE;
}
@ -645,12 +736,12 @@ instance_search (SharedHeader *header, void *data)
}
static SharedInstance*
find_custom_instance (SharedCategory* cat, MonoString *instance)
find_custom_instance (SharedCategory* cat, char *name)
{
InstanceSearch search;
search.cat_offset = (char*)cat - (char*)shared_area;
search.cat = cat;
search.instance = instance;
search.name = name;
search.list = NULL;
search.result = NULL;
foreach_shared_item (instance_search, &search);
@ -663,7 +754,7 @@ get_custom_instances_list (SharedCategory* cat)
InstanceSearch search;
search.cat_offset = (char*)cat - (char*)shared_area;
search.cat = cat;
search.instance = NULL;
search.name = NULL;
search.list = NULL;
search.result = NULL;
foreach_shared_item (instance_search, &search);
@ -896,11 +987,14 @@ mono_mem_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounterSample
sample->counterType = predef_counters [predef_categories [CATEGORY_MONO_MEM].first_counter + id].type;
switch (id) {
case COUNTER_MEM_NUM_OBJECTS:
sample->rawValue = mono_stats.new_object_count;
sample->rawValue = 0;
return TRUE;
case COUNTER_MEM_PHYS_TOTAL:
sample->rawValue = mono_determine_physical_ram_size ();;
return TRUE;
case COUNTER_MEM_PHYS_AVAILABLE:
sample->rawValue = mono_determine_physical_ram_available_size ();;
return TRUE;
}
return FALSE;
}
@ -1140,41 +1234,33 @@ custom_writable_update (ImplVtable *vtable, MonoBoolean do_incr, gint64 value)
}
static SharedInstance*
custom_get_instance (SharedCategory *cat, SharedCounter *scounter, MonoString* instance)
custom_get_instance (SharedCategory *cat, SharedCounter *scounter, char* name)
{
SharedInstance* inst;
unsigned char *ptr;
char *p;
int size, data_offset;
char *name;
inst = find_custom_instance (cat, instance);
inst = find_custom_instance (cat, name);
if (inst)
return inst;
name = mono_string_to_utf8 (instance);
size = sizeof (SharedInstance) + strlen (name);
size += 7;
size &= ~7;
data_offset = size;
size += (sizeof (guint64) * cat->num_counters);
perfctr_lock ();
ptr = shared_data_find_room (size);
if (!ptr) {
inst = (SharedInstance*) shared_data_reserve_room (size, FTYPE_INSTANCE);
if (!inst) {
perfctr_unlock ();
g_free (name);
return NULL;
}
inst = (SharedInstance*)ptr;
inst->header.extra = 0; /* data_offset could overflow here, so we leave this field unused */
inst->header.size = size;
inst->category_offset = (char*)cat - (char*)shared_area;
cat->num_instances++;
/* now copy the variable data */
p = inst->instance_name;
strcpy (p, name);
p += strlen (name) + 1;
inst->header.ftype = FTYPE_INSTANCE;
perfctr_unlock ();
g_free (name);
return inst;
}
@ -1193,24 +1279,33 @@ custom_vtable (SharedCounter *scounter, SharedInstance* inst, char *data)
return (ImplVtable*)vtable;
}
static gpointer
custom_get_value_address (SharedCounter *scounter, SharedInstance* sinst)
{
int offset = sizeof (SharedInstance) + strlen (sinst->instance_name);
offset += 7;
offset &= ~7;
offset += scounter->seq_num * sizeof (guint64);
return (char*)sinst + offset;
}
static void*
custom_get_impl (SharedCategory *cat, MonoString* counter, MonoString* instance, int *type)
{
SharedCounter *scounter;
SharedInstance* inst;
int size;
char *name;
scounter = find_custom_counter (cat, counter);
if (!scounter)
return NULL;
*type = simple_type_to_type [scounter->type];
inst = custom_get_instance (cat, scounter, instance);
name = mono_string_to_utf8 (counter);
inst = custom_get_instance (cat, scounter, name);
g_free (name);
if (!inst)
return NULL;
size = sizeof (SharedInstance) + strlen (inst->instance_name);
size += 7;
size &= ~7;
return custom_vtable (scounter, inst, (char*)inst + size + scounter->seq_num * sizeof (guint64));
return custom_vtable (scounter, inst, custom_get_value_address (scounter, inst));
}
static const CategoryDesc*
@ -1383,7 +1478,6 @@ mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoA
char *name = NULL;
char *chelp = NULL;
char **counter_info = NULL;
unsigned char *ptr;
char *p;
SharedCategory *cat;
@ -1419,14 +1513,11 @@ mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoA
if (size > 65535)
goto failure;
perfctr_lock ();
ptr = shared_data_find_room (size);
if (!ptr) {
cat = (SharedCategory*) shared_data_reserve_room (size, FTYPE_CATEGORY);
if (!cat) {
perfctr_unlock ();
goto failure;
}
cat = (SharedCategory*)ptr;
cat->header.extra = type;
cat->header.size = size;
cat->num_counters = num_counters;
cat->counters_data_size = counters_data_size;
/* now copy the vaiable data */
@ -1445,7 +1536,6 @@ mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoA
strcpy (p, counter_info [i * 2 + 1]);
p += strlen (counter_info [i * 2 + 1]) + 1;
}
cat->header.ftype = FTYPE_CATEGORY;
perfctr_unlock ();
result = TRUE;
@ -1466,6 +1556,8 @@ int
mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, MonoString *machine)
{
const CategoryDesc *cdesc;
SharedInstance *sinst;
char *name;
/* no support for counters on other machines */
/*FIXME: machine appears to be wrong
if (mono_string_compare_ascii (machine, "."))
@ -1476,7 +1568,10 @@ mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, Mo
scat = find_custom_category (category);
if (!scat)
return FALSE;
if (find_custom_instance (scat, instance))
name = mono_string_to_utf8 (instance);
sinst = find_custom_instance (scat, name);
g_free (name);
if (sinst)
return TRUE;
} else {
/* FIXME: search instance */
@ -1539,7 +1634,8 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
res = mono_array_new (domain, mono_get_string_class (), scat->num_counters);
for (i = 0; i < scat->num_counters; ++i) {
mono_array_setref (res, i, mono_string_new (domain, p + 1));
p += 1 + strlen (p + 1) + 1; /* skip counter type and name */
p += 2; /* skip counter type */
p += strlen (p) + 1; /* skip counter name */
p += strlen (p) + 1; /* skip counter help */
}
perfctr_unlock ();
@ -1691,6 +1787,65 @@ mono_perfcounter_instance_names (MonoString *category, MonoString *machine)
return mono_array_new (mono_domain_get (), mono_get_string_class (), 0);
}
}
typedef struct {
PerfCounterEnumCallback cb;
void *data;
} PerfCounterForeachData;
static gboolean
mono_perfcounter_foreach_shared_item (SharedHeader *header, gpointer data)
{
int i;
char *p, *name, *help;
unsigned char type;
int seq_num;
void *addr;
SharedCategory *cat;
SharedCounter *counter;
SharedInstance *inst;
PerfCounterForeachData *foreach_data = data;
if (header->ftype == FTYPE_CATEGORY) {
cat = (SharedCategory*)header;
p = cat->name;
p += strlen (p) + 1; /* skip category name */
p += strlen (p) + 1; /* skip category help */
for (i = 0; i < cat->num_counters; ++i) {
counter = (SharedCounter*) p;
type = (unsigned char)*p++;
seq_num = (int)*p++;
name = p;
p += strlen (p) + 1;
help = p;
p += strlen (p) + 1;
inst = custom_get_instance (cat, counter, name);
if (!inst)
return FALSE;
addr = custom_get_value_address (counter, inst);
if (!foreach_data->cb (cat->name, name, type, addr ? *(gint64*)addr : 0, foreach_data->data))
return FALSE;
}
}
return TRUE;
}
void
mono_perfcounter_foreach (PerfCounterEnumCallback cb, gpointer data)
{
PerfCounterForeachData foreach_data = { cb, data };
perfctr_lock ();
foreach_shared_item (mono_perfcounter_foreach_shared_item, &foreach_data);
perfctr_unlock ();
}
#else
void*
mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString* instance, MonoString* machine, int *type, MonoBoolean *custom)

View File

@ -2,8 +2,8 @@
#define __MONO_PERFCOUNTERS_H__
#include <glib.h>
#include <metadata/object.h>
#include <utils/mono-compiler.h>
#include <mono/metadata/object.h>
#include <mono/utils/mono-compiler.h>
typedef struct _MonoCounterSample MonoCounterSample;
@ -25,6 +25,8 @@ MonoArray* mono_perfcounter_category_names (MonoString *machine) MONO_INTERNAL
MonoArray* mono_perfcounter_counter_names (MonoString *category, MonoString *machine) MONO_INTERNAL;
MonoArray* mono_perfcounter_instance_names (MonoString *category, MonoString *machine) MONO_INTERNAL;
typedef gboolean (*PerfCounterEnumCallback) (char *category_name, char *name, unsigned char type, gint64 value, gpointer user_data);
MONO_API void mono_perfcounter_foreach (PerfCounterEnumCallback cb, gpointer user_data);
#endif /* __MONO_PERFCOUNTERS_H__ */

View File

@ -0,0 +1,124 @@
/*
* mono-route.c: Read the network routing tables using sysctl(3) calls
* Required for Unix-like systems that don't have Linux's /proc/net/route
*
* Author:
* Ben Woods (woodsb02@gmail.com)
*/
#if defined(PLATFORM_MACOSX) || defined(PLATFORM_BSD)
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <stdlib.h>
#include <string.h>
#include <mono/metadata/object.h>
#include <mono/metadata/mono-route.h>
extern MonoBoolean ves_icall_System_Net_NetworkInformation_MacOsIPInterfaceProperties_ParseRouteInfo_internal(MonoString *iface, MonoArray **gw_addr_list)
{
size_t needed;
in_addr_t in;
int mib[6];
int num_gws=0, gwnum=0;
unsigned int ifindex = 0;
char *buf, *next, *lim, *ifacename;
struct rt_msghdr *rtm;
MonoDomain *domain = mono_domain_get ();
ifacename = mono_string_to_utf8(iface);
if ((ifindex = if_nametoindex(ifacename)) == 0)
return FALSE;
g_free(ifacename);
// MIB array defining data to read from sysctl
mib[0] = CTL_NET; // Networking
mib[1] = PF_ROUTE; // Routing messages
mib[2] = 0; // Protocol number (always zero)
mib[3] = AF_INET; // Address family (IPv4)
mib[4] = NET_RT_DUMP; // Dump routing table
mib[5] = 0; //
// First sysctl call with oldp set to NULL to determine size of available data
if (sysctl(mib, G_N_ELEMENTS(mib), NULL, &needed, NULL, 0) < 0)
return FALSE;
// Allocate suffcient memory for available data based on the previous sysctl call
if ((buf = malloc(needed)) == NULL)
return FALSE;
// Second sysctl call to retrieve data into appropriately sized buffer
if (sysctl(mib, G_N_ELEMENTS(mib), buf, &needed, NULL, 0) < 0)
return FALSE;
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
if (rtm->rtm_version != RTM_VERSION)
continue;
if (rtm->rtm_index != ifindex)
continue;
if((in = gateway_from_rtm(rtm)) == 0)
continue;
num_gws++;
}
*gw_addr_list = mono_array_new(domain, mono_get_string_class (), num_gws);
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
if (rtm->rtm_version != RTM_VERSION)
continue;
if (rtm->rtm_index != ifindex)
continue;
if ((in = gateway_from_rtm(rtm)) == 0)
continue;
MonoString *addr_string;
char addr [16], *ptr;
int len;
ptr = (char *) &in;
len = snprintf(addr, sizeof(addr), "%u.%u.%u.%u",
(unsigned char) ptr [0],
(unsigned char) ptr [1],
(unsigned char) ptr [2],
(unsigned char) ptr [3]);
if ((len >= sizeof(addr)) || (len < 0))
// snprintf output truncated
continue;
addr_string = mono_string_new (domain, addr);
mono_array_setref (*gw_addr_list, gwnum, addr_string);
gwnum++;
}
free(buf);
return TRUE;
}
in_addr_t gateway_from_rtm(struct rt_msghdr *rtm)
{
struct sockaddr *gw;
unsigned int l;
struct sockaddr *addr = (struct sockaddr *)(rtm + 1);
l = roundup(addr->sa_len, sizeof(long)); \
gw = (struct sockaddr *)((char *) addr + l); \
if (rtm->rtm_addrs & RTA_GATEWAY) {
if(gw->sa_family == AF_INET) {
struct sockaddr_in *sockin = (struct sockaddr_in *)gw;
return(sockin->sin_addr.s_addr);
}
}
return 0;
}
#endif /* #if defined(PLATFORM_MACOSX) || defined(PLATFORM_BSD) */

View File

@ -0,0 +1,23 @@
#ifndef __MONO_ROUTE_H__
#define __MONO_ROUTE_H__
#if defined(PLATFORM_MACOSX) || defined(PLATFORM_BSD)
#include <sys/socket.h>
#ifdef HOST_IOS
// The iOS SDK does not provide the net/route.h header but using the Darwin version works fine.
#include "../../support/ios/net/route.h"
#else
#include <net/route.h>
#endif
#include <mono/metadata/object-internals.h>
in_addr_t gateway_from_rtm (struct rt_msghdr *rtm) MONO_INTERNAL;
/* Category icalls */
extern MonoBoolean ves_icall_System_Net_NetworkInformation_MacOsIPInterfaceProperties_ParseRouteInfo_internal (MonoString *iface, MonoArray **gw_addr_list) MONO_INTERNAL;
#endif /* #if defined(PLATFORM_MACOSX) || defined(PLATFORM_BSD) */
#endif /* __MONO_ROUTE_H__ */

View File

@ -0,0 +1,959 @@
/*
* security.c: Security internal calls
*
* Author:
* Sebastien Pouliot <sebastien@ximian.com>
*
* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mono/metadata/assembly.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/image.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/security.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strenc.h>
#ifdef HOST_WIN32
#include <aclapi.h>
#include <accctrl.h>
#ifndef PROTECTED_DACL_SECURITY_INFORMATION
#define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000L
#endif
#else
#include <config.h>
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/* Disclaimers */
#if defined(__GNUC__)
#ifndef HAVE_GETGRGID_R
#warning Non-thread safe getgrgid being used!
#endif
#ifndef HAVE_GETGRNAM_R
#warning Non-thread safe getgrnam being used!
#endif
#ifndef HAVE_GETPWNAM_R
#warning Non-thread safe getpwnam being used!
#endif
#ifndef HAVE_GETPWUID_R
#warning Non-thread safe getpwuid being used!
#endif
#endif /* defined(__GNUC__) */
#endif /* not HOST_WIN32 */
/* internal functions - reuse driven */
#ifdef HOST_WIN32
/* ask a server to translate a SID into a textual representation */
static gunichar2*
GetSidName (gunichar2 *server, PSID sid, gint32 *size)
{
gunichar2 *uniname = NULL;
DWORD cchName = 0;
DWORD cchDomain = 0;
SID_NAME_USE peUse; /* out */
LookupAccountSid (server, sid, NULL, &cchName, NULL,
&cchDomain, &peUse);
if ((cchName > 0) && (cchDomain > 0)) {
gunichar2 *user = g_malloc0 ((cchName + 1) * 2);
gunichar2 *domain = g_malloc0 ((cchDomain + 1) * 2);
LookupAccountSid (server, sid, user, &cchName, domain,
&cchDomain, &peUse);
if (cchName > 0) {
if (cchDomain > 0) {
/* domain/machine name included (+ sepearator) */
*size = cchName + cchDomain + 1;
uniname = g_malloc0 ((*size + 1) * 2);
memcpy (uniname, domain, cchDomain * 2);
*(uniname + cchDomain) = '\\';
memcpy (uniname + cchDomain + 1, user, cchName * 2);
g_free (user);
}
else {
/* no domain / machine */
*size = cchName;
uniname = user;
}
}
else {
/* nothing -> return NULL */
g_free (user);
}
g_free (domain);
}
return uniname;
}
#else /* not HOST_WIN32 */
#define MONO_SYSCONF_DEFAULT_SIZE ((size_t) 1024)
/*
* Ensure we always get a valid (usable) value from sysconf.
* In case of error, we return the default value.
*/
static size_t mono_sysconf (int name)
{
size_t size = (size_t) sysconf (name);
/* default value */
return (size == -1) ? MONO_SYSCONF_DEFAULT_SIZE : size;
}
static gchar*
GetTokenName (uid_t uid)
{
gchar *uname = NULL;
#ifdef HAVE_GETPWUID_R
struct passwd pwd;
size_t fbufsize;
gchar *fbuf;
gint32 retval;
#endif
struct passwd *p = NULL;
gboolean result;
#ifdef HAVE_GETPWUID_R
#ifdef _SC_GETPW_R_SIZE_MAX
fbufsize = mono_sysconf (_SC_GETPW_R_SIZE_MAX);
#else
fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
#endif
fbuf = g_malloc0 (fbufsize);
retval = getpwuid_r (uid, &pwd, fbuf, fbufsize, &p);
result = ((retval == 0) && (p == &pwd));
#else
/* default to non thread-safe but posix compliant function */
p = getpwuid (uid);
result = (p != NULL);
#endif
if (result) {
uname = g_strdup (p->pw_name);
}
#ifdef HAVE_GETPWUID_R
g_free (fbuf);
#endif
return uname;
}
static gboolean
IsMemberInList (uid_t user, struct group *g)
{
gboolean result = FALSE;
gchar *utf8_username = GetTokenName (user);
if (!utf8_username)
return FALSE;
if (g) {
gchar **users = g->gr_mem;
while (*users) {
gchar *u = *(users);
if (strcmp (utf8_username, u) == 0) {
result = TRUE;
break;
}
users++;
}
}
g_free (utf8_username);
return result;
}
static gboolean
IsDefaultGroup (uid_t user, gid_t group)
{
#ifdef HAVE_GETPWUID_R
struct passwd pwd;
size_t fbufsize;
gchar *fbuf;
gint32 retval;
#endif
struct passwd *p = NULL;
gboolean result;
#ifdef HAVE_GETPWUID_R
#ifdef _SC_GETPW_R_SIZE_MAX
fbufsize = mono_sysconf (_SC_GETPW_R_SIZE_MAX);
#else
fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
#endif
fbuf = g_malloc0 (fbufsize);
retval = getpwuid_r (user, &pwd, fbuf, fbufsize, &p);
result = ((retval == 0) && (p == &pwd));
#else
/* default to non thread-safe but posix compliant function */
p = getpwuid (user);
result = (p != NULL);
#endif
if (result) {
result = (p->pw_gid == group);
}
#ifdef HAVE_GETPWUID_R
g_free (fbuf);
#endif
return result;
}
static gboolean
IsMemberOf (gid_t user, struct group *g)
{
if (!g)
return FALSE;
/* is it the user default group */
if (IsDefaultGroup (user, g->gr_gid))
return TRUE;
/* is the user in the group list */
return IsMemberInList (user, g);
}
#endif
/* ICALLS */
/* System.Security.Principal.WindowsIdentity */
gpointer
ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
{
gpointer token = NULL;
#ifdef HOST_WIN32
/* Note: This isn't a copy of the Token - we must not close it!!!
* http://www.develop.com/kbrown/book/html/whatis_windowsprincipal.html
*/
/* thread may be impersonating somebody */
if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, 1, &token) == 0) {
/* if not take the process identity */
OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token);
}
#else
token = GINT_TO_POINTER (geteuid ());
#endif
return token;
}
MonoString*
ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token)
{
MonoString *result = NULL;
gunichar2 *uniname = NULL;
gint32 size = 0;
#ifdef HOST_WIN32
GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
if (size > 0) {
TOKEN_USER *tu = g_malloc0 (size);
if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) {
uniname = GetSidName (NULL, tu->User.Sid, &size);
}
g_free (tu);
}
#else
gchar *uname = GetTokenName ((uid_t) GPOINTER_TO_INT (token));
if (uname) {
size = strlen (uname);
uniname = g_utf8_to_utf16 (uname, size, NULL, NULL, NULL);
g_free (uname);
}
#endif /* HOST_WIN32 */
if (size > 0) {
result = mono_string_new_utf16 (mono_domain_get (), uniname, size);
}
else
result = mono_string_new (mono_domain_get (), "");
if (uniname)
g_free (uniname);
return result;
}
gpointer
ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString *username)
{
#ifdef HOST_WIN32
gpointer token = NULL;
/* TODO: MS has something like this working in Windows 2003 (client and
* server) but works only for domain accounts (so it's quite limiting).
* http://www.develop.com/kbrown/book/html/howto_logonuser.html
*/
g_warning ("Unsupported on Win32 (anyway requires W2K3 minimum)");
#else /* HOST_WIN32*/
#ifdef HAVE_GETPWNAM_R
struct passwd pwd;
size_t fbufsize;
gchar *fbuf;
gint32 retval;
#endif
gpointer token = (gpointer) -2;
struct passwd *p;
gchar *utf8_name;
gboolean result;
utf8_name = mono_unicode_to_external (mono_string_chars (username));
#ifdef HAVE_GETPWNAM_R
#ifdef _SC_GETPW_R_SIZE_MAX
fbufsize = mono_sysconf (_SC_GETPW_R_SIZE_MAX);
#else
fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
#endif
fbuf = g_malloc0 (fbufsize);
retval = getpwnam_r (utf8_name, &pwd, fbuf, fbufsize, &p);
result = ((retval == 0) && (p == &pwd));
#else
/* default to non thread-safe but posix compliant function */
p = getpwnam (utf8_name);
result = (p != NULL);
#endif
if (result) {
token = GINT_TO_POINTER (p->pw_uid);
}
#ifdef HAVE_GETPWNAM_R
g_free (fbuf);
#endif
g_free (utf8_name);
#endif
return token;
}
/* http://www.dotnet247.com/247reference/msgs/39/195403.aspx
// internal static string[] WindowsIdentity._GetRoles (IntPtr token)
*/
MonoArray*
ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token)
{
MonoArray *array = NULL;
MonoDomain *domain = mono_domain_get ();
#ifdef HOST_WIN32
gint32 size = 0;
GetTokenInformation (token, TokenGroups, NULL, size, (PDWORD)&size);
if (size > 0) {
TOKEN_GROUPS *tg = g_malloc0 (size);
if (GetTokenInformation (token, TokenGroups, tg, size, (PDWORD)&size)) {
int i=0;
int num = tg->GroupCount;
array = mono_array_new (domain, mono_get_string_class (), num);
for (i=0; i < num; i++) {
gint32 size = 0;
gunichar2 *uniname = GetSidName (NULL, tg->Groups [i].Sid, &size);
if (uniname) {
MonoString *str = mono_string_new_utf16 (domain, uniname, size);
mono_array_setref (array, i, str);
g_free (uniname);
}
}
}
g_free (tg);
}
#else
/* POSIX-compliant systems should use IsMemberOfGroupId or IsMemberOfGroupName */
g_warning ("WindowsIdentity._GetRoles should never be called on POSIX");
#endif
if (!array) {
/* return empty array of string, i.e. string [0] */
array = mono_array_new (domain, mono_get_string_class (), 0);
}
return array;
}
/* System.Security.Principal.WindowsImpersonationContext */
gboolean
ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken (gpointer token)
{
gboolean result = TRUE;
#ifdef HOST_WIN32
result = (CloseHandle (token) != 0);
#endif
return result;
}
gpointer
ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (gpointer token)
{
gpointer dupe = NULL;
#ifdef HOST_WIN32
if (DuplicateToken (token, SecurityImpersonation, &dupe) == 0) {
dupe = NULL;
}
#else
dupe = token;
#endif
return dupe;
}
gboolean
ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken (gpointer token)
{
/* Posix version implemented in /mono/mono/io-layer/security.c */
return (ImpersonateLoggedOnUser (token) != 0);
}
gboolean
ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf (void)
{
/* Posix version implemented in /mono/mono/io-layer/security.c */
return (RevertToSelf () != 0);
}
/* System.Security.Principal.WindowsPrincipal */
gboolean
ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer user, gpointer group)
{
gboolean result = FALSE;
#ifdef HOST_WIN32
/* The convertion from an ID to a string is done in managed code for Windows */
g_warning ("IsMemberOfGroupId should never be called on Win32");
#else /* HOST_WIN32 */
#ifdef HAVE_GETGRGID_R
struct group grp;
size_t fbufsize;
gchar *fbuf;
gint32 retval;
#endif
struct group *g = NULL;
#ifdef HAVE_GETGRGID_R
#ifdef _SC_GETGR_R_SIZE_MAX
fbufsize = mono_sysconf (_SC_GETGR_R_SIZE_MAX);
#else
fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
#endif
fbuf = g_malloc0 (fbufsize);
retval = getgrgid_r ((gid_t) GPOINTER_TO_INT (group), &grp, fbuf, fbufsize, &g);
result = ((retval == 0) && (g == &grp));
#else
/* default to non thread-safe but posix compliant function */
g = getgrgid ((gid_t) GPOINTER_TO_INT (group));
result = (g != NULL);
#endif
if (result) {
result = IsMemberOf ((uid_t) GPOINTER_TO_INT (user), g);
}
#ifdef HAVE_GETGRGID_R
g_free (fbuf);
#endif
#endif /* HOST_WIN32 */
return result;
}
gboolean
ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpointer user, MonoString *group)
{
gboolean result = FALSE;
#ifdef HOST_WIN32
/* Windows version use a cache built using WindowsIdentity._GetRoles */
g_warning ("IsMemberOfGroupName should never be called on Win32");
#else /* HOST_WIN32 */
gchar *utf8_groupname;
utf8_groupname = mono_unicode_to_external (mono_string_chars (group));
if (utf8_groupname) {
struct group *g = NULL;
#ifdef HAVE_GETGRNAM_R
struct group grp;
gchar *fbuf;
gint32 retval;
#ifdef _SC_GETGR_R_SIZE_MAX
size_t fbufsize = mono_sysconf (_SC_GETGR_R_SIZE_MAX);
#else
size_t fbufsize = MONO_SYSCONF_DEFAULT_SIZE;
#endif
fbuf = g_malloc0 (fbufsize);
retval = getgrnam_r (utf8_groupname, &grp, fbuf, fbufsize, &g);
result = ((retval == 0) && (g == &grp));
#else
/* default to non thread-safe but posix compliant function */
g = getgrnam (utf8_groupname);
result = (g != NULL);
#endif
if (result) {
result = IsMemberOf ((uid_t) GPOINTER_TO_INT (user), g);
}
#ifdef HAVE_GETGRNAM_R
g_free (fbuf);
#endif
g_free (utf8_groupname);
}
#endif /* HOST_WIN32 */
return result;
}
/* Mono.Security.Cryptography IO related internal calls */
#ifdef HOST_WIN32
static PSID
GetAdministratorsSid (void)
{
SID_IDENTIFIER_AUTHORITY admins = SECURITY_NT_AUTHORITY;
PSID pSid = NULL;
if (!AllocateAndInitializeSid (&admins, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid))
return NULL;
/* Note: this SID must be freed with FreeSid () */
return pSid;
}
static PSID
GetEveryoneSid (void)
{
SID_IDENTIFIER_AUTHORITY everyone = SECURITY_WORLD_SID_AUTHORITY;
PSID pSid = NULL;
if (!AllocateAndInitializeSid (&everyone, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSid))
return NULL;
/* Note: this SID must be freed with FreeSid () */
return pSid;
}
static PSID
GetCurrentUserSid (void)
{
PSID sid = NULL;
guint32 size = 0;
gpointer token = ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken ();
GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size);
if (size > 0) {
TOKEN_USER *tu = g_malloc0 (size);
if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) {
DWORD length = GetLengthSid (tu->User.Sid);
sid = (PSID) g_malloc0 (length);
if (!CopySid (length, sid, tu->User.Sid)) {
g_free (sid);
sid = NULL;
}
}
g_free (tu);
}
/* Note: this SID must be freed with g_free () */
return sid;
}
static ACCESS_MASK
GetRightsFromSid (PSID sid, PACL acl)
{
ACCESS_MASK rights = 0;
TRUSTEE trustee;
BuildTrusteeWithSidW (&trustee, sid);
if (GetEffectiveRightsFromAcl (acl, &trustee, &rights) != ERROR_SUCCESS)
return 0;
return rights;
}
static gboolean
IsMachineProtected (gunichar2 *path)
{
gboolean success = FALSE;
PACL pDACL = NULL;
PSID pEveryoneSid = NULL;
DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, NULL);
if (dwRes != ERROR_SUCCESS)
return FALSE;
/* We check that Everyone is still limited to READ-ONLY -
but not if new entries have been added by an Administrator */
pEveryoneSid = GetEveryoneSid ();
if (pEveryoneSid) {
ACCESS_MASK rights = GetRightsFromSid (pEveryoneSid, pDACL);
/* http://msdn.microsoft.com/library/en-us/security/security/generic_access_rights.asp?frame=true */
success = (rights == (READ_CONTROL | SYNCHRONIZE | FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES));
FreeSid (pEveryoneSid);
}
/* Note: we don't need to check our own access -
we'll know soon enough when reading the file */
if (pDACL)
LocalFree (pDACL);
return success;
}
static gboolean
IsUserProtected (gunichar2 *path)
{
gboolean success = FALSE;
PACL pDACL = NULL;
PSID pEveryoneSid = NULL;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSecurityDescriptor);
if (dwRes != ERROR_SUCCESS)
return FALSE;
/* We check that our original entries in the ACL are in place -
but not if new entries have been added by the user */
/* Everyone should be denied */
pEveryoneSid = GetEveryoneSid ();
if (pEveryoneSid) {
ACCESS_MASK rights = GetRightsFromSid (pEveryoneSid, pDACL);
success = (rights == 0);
FreeSid (pEveryoneSid);
}
/* Note: we don't need to check our own access -
we'll know soon enough when reading the file */
if (pSecurityDescriptor)
LocalFree (pSecurityDescriptor);
return success;
}
static gboolean
ProtectMachine (gunichar2 *path)
{
PSID pEveryoneSid = GetEveryoneSid ();
PSID pAdminsSid = GetAdministratorsSid ();
DWORD retval = -1;
if (pEveryoneSid && pAdminsSid) {
PACL pDACL = NULL;
EXPLICIT_ACCESS ea [2];
ZeroMemory (&ea, 2 * sizeof (EXPLICIT_ACCESS));
/* grant all access to the BUILTIN\Administrators group */
BuildTrusteeWithSidW (&ea [0].Trustee, pAdminsSid);
ea [0].grfAccessPermissions = GENERIC_ALL;
ea [0].grfAccessMode = SET_ACCESS;
ea [0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea [0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea [0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
/* read-only access everyone */
BuildTrusteeWithSidW (&ea [1].Trustee, pEveryoneSid);
ea [1].grfAccessPermissions = GENERIC_READ;
ea [1].grfAccessMode = SET_ACCESS;
ea [1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea [1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea [1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
retval = SetEntriesInAcl (2, ea, NULL, &pDACL);
if (retval == ERROR_SUCCESS) {
/* with PROTECTED_DACL_SECURITY_INFORMATION we */
/* remove any existing ACL (like inherited ones) */
retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL, NULL, pDACL, NULL);
}
if (pDACL)
LocalFree (pDACL);
}
if (pEveryoneSid)
FreeSid (pEveryoneSid);
if (pAdminsSid)
FreeSid (pAdminsSid);
return (retval == ERROR_SUCCESS);
}
static gboolean
ProtectUser (gunichar2 *path)
{
DWORD retval = -1;
PSID pCurrentSid = GetCurrentUserSid ();
if (pCurrentSid) {
PACL pDACL = NULL;
EXPLICIT_ACCESS ea;
ZeroMemory (&ea, sizeof (EXPLICIT_ACCESS));
/* grant exclusive access to the current user */
BuildTrusteeWithSidW (&ea.Trustee, pCurrentSid);
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
retval = SetEntriesInAcl (1, &ea, NULL, &pDACL);
if (retval == ERROR_SUCCESS) {
/* with PROTECTED_DACL_SECURITY_INFORMATION we
remove any existing ACL (like inherited ones) */
retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL, NULL, pDACL, NULL);
}
if (pDACL)
LocalFree (pDACL);
g_free (pCurrentSid); /* g_malloc0 */
}
return (retval == ERROR_SUCCESS);
}
#else
static gboolean
IsProtected (MonoString *path, gint32 protection)
{
gboolean result = FALSE;
gchar *utf8_name = mono_unicode_to_external (mono_string_chars (path));
if (utf8_name) {
struct stat st;
if (stat (utf8_name, &st) == 0) {
result = (((st.st_mode & 0777) & protection) == 0);
}
g_free (utf8_name);
}
return result;
}
static gboolean
Protect (MonoString *path, gint32 file_mode, gint32 add_dir_mode)
{
gboolean result = FALSE;
gchar *utf8_name = mono_unicode_to_external (mono_string_chars (path));
if (utf8_name) {
struct stat st;
if (stat (utf8_name, &st) == 0) {
int mode = file_mode;
if (st.st_mode & S_IFDIR)
mode |= add_dir_mode;
result = (chmod (utf8_name, mode) == 0);
}
g_free (utf8_name);
}
return result;
}
#endif /* not HOST_WIN32 */
MonoBoolean
ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure (MonoString *root)
{
#if HOST_WIN32
gint32 flags;
/* ACL are nice... unless you have FAT or other uncivilized filesystem */
if (!GetVolumeInformation (mono_string_chars (root), NULL, 0, NULL, NULL, (LPDWORD)&flags, NULL, 0))
return FALSE;
return ((flags & FS_PERSISTENT_ACLS) == FS_PERSISTENT_ACLS);
#else
/* we assume some kind of security is applicable outside Windows */
return TRUE;
#endif
}
MonoBoolean
ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected (MonoString *path)
{
gboolean ret = FALSE;
/* no one, but the owner, should have write access to the directory */
#ifdef HOST_WIN32
ret = IsMachineProtected (mono_string_chars (path));
#else
ret = IsProtected (path, (S_IWGRP | S_IWOTH));
#endif
return ret;
}
MonoBoolean
ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected (MonoString *path)
{
gboolean ret = FALSE;
/* no one, but the user, should have access to the directory */
#ifdef HOST_WIN32
ret = IsUserProtected (mono_string_chars (path));
#else
ret = IsProtected (path, (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH));
#endif
return ret;
}
MonoBoolean
ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine (MonoString *path)
{
gboolean ret = FALSE;
/* read/write to owner, read to everyone else */
#ifdef HOST_WIN32
ret = ProtectMachine (mono_string_chars (path));
#else
ret = Protect (path, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), (S_IXUSR | S_IXGRP | S_IXOTH));
#endif
return ret;
}
MonoBoolean
ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser (MonoString *path)
{
gboolean ret = FALSE;
/* read/write to user, no access to everyone else */
#ifdef HOST_WIN32
ret = ProtectUser (mono_string_chars (path));
#else
ret = Protect (path, (S_IRUSR | S_IWUSR), S_IXUSR);
#endif
return ret;
}
/*
* Returns TRUE if there is "something" where the Authenticode signature is
* normally located. Returns FALSE is data directory is empty.
*
* Note: Neither the structure nor the signature is verified by this function.
*/
MonoBoolean
ves_icall_System_Security_Policy_Evidence_IsAuthenticodePresent (MonoReflectionAssembly *refass)
{
if (refass && refass->assembly && refass->assembly->image) {
return mono_image_has_authenticode_entry (refass->assembly->image);
}
return FALSE;
}
/* System.Security.SecureString related internal calls */
static MonoImage *system_security_assembly = NULL;
void
ves_icall_System_Security_SecureString_DecryptInternal (MonoArray *data, MonoObject *scope)
{
invoke_protected_memory_method (data, scope, FALSE);
}
void
ves_icall_System_Security_SecureString_EncryptInternal (MonoArray* data, MonoObject *scope)
{
invoke_protected_memory_method (data, scope, TRUE);
}
void invoke_protected_memory_method (MonoArray *data, MonoObject *scope, gboolean encrypt)
{
MonoClass *klass;
MonoMethod *method;
void *params [2];
if (system_security_assembly == NULL) {
system_security_assembly = mono_image_loaded ("System.Security");
if (!system_security_assembly) {
MonoAssembly *sa = mono_assembly_open ("System.Security.dll", NULL);
if (!sa)
g_assert_not_reached ();
system_security_assembly = mono_assembly_get_image (sa);
}
}
klass = mono_class_from_name (system_security_assembly,
"System.Security.Cryptography", "ProtectedMemory");
method = mono_class_get_method_from_name (klass, encrypt ? "Protect" : "Unprotect", 2);
params [0] = data;
params [1] = scope; /* MemoryProtectionScope.SameProcess */
mono_runtime_invoke (method, NULL, params, NULL);
}

View File

@ -13,6 +13,7 @@
#include <mono/metadata/runtime.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/mono-counters.h>
#ifdef HAVE_NULL_GC
@ -22,6 +23,8 @@ mono_gc_base_init (void)
MonoThreadInfoCallbacks cb;
int dummy;
mono_counters_init ();
memset (&cb, 0, sizeof (cb));
/* TODO: This casts away an incompatible pointer type warning in the same
manner that boehm-gc does it. This is probably worth investigating
@ -231,8 +234,14 @@ mono_gc_is_critical_method (MonoMethod *method)
return FALSE;
}
int
mono_gc_get_aligned_size_for_allocator (int size)
{
return size;
}
MonoMethod*
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size)
{
return NULL;
}

View File

@ -82,7 +82,8 @@
#define mono_assert_not_reached() g_assert_not_reached()
#endif
#define MONO_CHECK_ARG(arg, expr) G_STMT_START{ \
/* Use this as MONO_CHECK_ARG_NULL (arg,expr,) in functions returning void */
#define MONO_CHECK_ARG(arg, expr, retval) G_STMT_START{ \
if (G_UNLIKELY (!(expr))) \
{ \
MonoException *ex; \
@ -91,16 +92,19 @@
if (arg) {} /* check if the name exists */ \
ex = mono_get_exception_argument (#arg, msg); \
g_free (msg); \
mono_raise_exception (ex); \
mono_set_pending_exception (ex); \
return retval; \
}; }G_STMT_END
#define MONO_CHECK_ARG_NULL(arg) G_STMT_START{ \
/* Use this as MONO_CHECK_ARG_NULL (arg,) in functions returning void */
#define MONO_CHECK_ARG_NULL(arg, retval) G_STMT_START{ \
if (G_UNLIKELY (arg == NULL)) \
{ \
MonoException *ex; \
if (arg) {} /* check if the name exists */ \
ex = mono_get_exception_argument_null (#arg); \
mono_raise_exception (ex); \
mono_set_pending_exception (ex); \
return retval; \
}; }G_STMT_END
/* 16 == default capacity */
@ -285,11 +289,6 @@ typedef struct {
MonoString *type_name;
} MonoTypeLoadException;
typedef struct {
MonoException base;
MonoObject *wrapped_exception;
} MonoRuntimeWrappedException;
typedef struct {
MonoObject object;
MonoObject *async_state;
@ -380,6 +379,7 @@ typedef struct {
MonoObject obj;
gint32 il_offset;
gint32 native_offset;
gint64 method_address;
MonoReflectionMethod *method;
MonoString *filename;
gint32 line;
@ -531,6 +531,37 @@ typedef struct {
gpointer ICU_collator;
} MonoCompareInfo;
typedef struct {
MonoObject obj;
MonoString *NativeName;
MonoArray *ShortDatePatterns;
MonoArray *YearMonthPatterns;
MonoArray *LongDatePatterns;
MonoString *MonthDayPattern;
MonoArray *EraNames;
MonoArray *AbbreviatedEraNames;
MonoArray *AbbreviatedEnglishEraNames;
MonoArray *DayNames;
MonoArray *AbbreviatedDayNames;
MonoArray *SuperShortDayNames;
MonoArray *MonthNames;
MonoArray *AbbreviatedMonthNames;
MonoArray *GenitiveMonthNames;
MonoArray *GenitiveAbbreviatedMonthNames;
} MonoCalendarData;
typedef struct {
MonoObject obj;
MonoString *AMDesignator;
MonoString *PMDesignator;
MonoString *TimeSeparator;
MonoArray *LongTimePatterns;
MonoArray *ShortTimePatterns;
guint32 FirstDayOfWeek;
guint32 CalendarWeekRule;
} MonoCultureData;
typedef struct {
MonoObject obj;
MonoBoolean is_read_only;
@ -618,7 +649,7 @@ typedef void (*MonoFreeMethodFunc) (MonoDomain *domain, MonoMethod *meth
/* Used to initialize the method pointers inside vtables */
typedef gboolean (*MonoInitVTableFunc) (MonoVTable *vtable);
void mono_set_pending_exception (MonoException *exc) MONO_INTERNAL;
MONO_COLD void mono_set_pending_exception (MonoException *exc) MONO_INTERNAL;
/* remoting and async support */
@ -1415,7 +1446,7 @@ void mono_reflection_create_unmanaged_type (MonoReflectionType *type) MON
void mono_reflection_register_with_runtime (MonoReflectionType *type) MONO_INTERNAL;
void mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info, MonoError *error) MONO_INTERNAL;
MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token) MONO_INTERNAL;
MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error) MONO_INTERNAL;
MonoArray* mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass) MONO_INTERNAL;

View File

@ -73,6 +73,7 @@ DECL_OFFSET(MonoDelegate, method)
DECL_OFFSET(MonoDelegate, method_code)
DECL_OFFSET(MonoInternalThread, tid)
DECL_OFFSET(MonoInternalThread, small_id)
DECL_OFFSET(MonoInternalThread, static_data)
DECL_OFFSET(MonoMulticastDelegate, prev)
@ -110,9 +111,8 @@ DECL_OFFSET(MonoTypedRef, klass)
DECL_OFFSET(MonoTypedRef, value)
//Internal structs
DECL_OFFSET(MonoThreadsSync, owner)
DECL_OFFSET(MonoThreadsSync, status)
DECL_OFFSET(MonoThreadsSync, nest)
DECL_OFFSET(MonoThreadsSync, entry_count)
#if defined (HAVE_SGEN_GC) && !defined (HAVE_KW_THREAD)
DECL_OFFSET(SgenThreadInfo, tlab_next_addr)
@ -162,18 +162,13 @@ DECL_OFFSET(MonoLMF, ebp)
DECL_OFFSET(MonoLMF, eip)
#endif
#ifdef TARGET_ARM
#if defined(TARGET_ARM) || defined(TARGET_ARM64)
DECL_OFFSET (MonoContext, pc)
DECL_OFFSET (MonoContext, regs)
DECL_OFFSET (MonoContext, fregs)
DECL_OFFSET(MonoLMF, method)
DECL_OFFSET(MonoLMF, lmf_addr)
DECL_OFFSET(MonoLMF, sp)
DECL_OFFSET(MonoLMF, fp)
DECL_OFFSET(MonoLMF, ip)
DECL_OFFSET(MonoLMF, iregs)
DECL_OFFSET(MonoLMF, fregs)
DECL_OFFSET(SeqPointInfo, bp_addrs)
DECL_OFFSET(SeqPointInfo, ss_trigger_page)
@ -182,6 +177,20 @@ DECL_OFFSET(DynCallArgs, res)
DECL_OFFSET(DynCallArgs, res2)
#endif
#if defined(TARGET_ARM)
DECL_OFFSET(MonoLMF, sp)
DECL_OFFSET(MonoLMF, fp)
DECL_OFFSET(MonoLMF, ip)
DECL_OFFSET(MonoLMF, iregs)
DECL_OFFSET(MonoLMF, fregs)
#elif defined(TARGET_ARM64)
DECL_OFFSET(MonoLMF, pc)
DECL_OFFSET(MonoLMF, gregs)
DECL_OFFSET(DynCallArgs, fpregs)
DECL_OFFSET(DynCallArgs, n_fpargs)
DECL_OFFSET(DynCallArgs, n_fpret)
#endif
#ifdef TARGET_AMD64
DECL_OFFSET(MonoContext, rax)
DECL_OFFSET(MonoContext, rcx)

View File

@ -15,7 +15,6 @@
#endif
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/tabledefs.h>
@ -276,8 +275,6 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
MonoClass *klass;
gchar *full_name;
MONO_ARCH_SAVE_REGS;
if (vtable->initialized)
return NULL;
@ -986,7 +983,7 @@ mono_class_compute_gc_descriptor (MonoClass *class)
class->gc_descr = (gpointer)mono_gc_make_descr_for_string (bitmap, 2);
} else if (class->rank) {
mono_class_compute_gc_descriptor (class->element_class);
if (!class->element_class->valuetype) {
if (MONO_TYPE_IS_REFERENCE (&class->element_class->byval_arg)) {
gsize abm = 1;
class->gc_descr = mono_gc_make_descr_for_array (class->byval_arg.type == MONO_TYPE_SZARRAY, &abm, 1, sizeof (gpointer));
/*printf ("new array descriptor: 0x%x for %s.%s\n", class->gc_descr,
@ -1851,6 +1848,27 @@ mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class)
return NULL;
}
static gpointer*
alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
{
size_t alloc_offset;
/*
* We want the pointer to the MonoVTable aligned to 8 bytes because SGen uses three
* address bits. The IMT has an odd number of entries, however, so on 32 bits the
* alignment will be off. In that case we allocate 4 more bytes and skip over them.
*/
if (sizeof (gpointer) == 4 && (imt_table_bytes & 7)) {
g_assert ((imt_table_bytes & 7) == 4);
vtable_size += 4;
alloc_offset = 4;
} else {
alloc_offset = 0;
}
return (gpointer*) ((char*)mono_domain_alloc0 (domain, vtable_size) + alloc_offset);
}
static MonoVTable *
mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
@ -1859,7 +1877,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
MonoClassField *field;
char *t;
int i, vtable_slots;
int imt_table_bytes = 0;
size_t imt_table_bytes;
int gc_bits;
guint32 vtable_size, class_size;
guint32 cindex;
@ -1934,26 +1952,26 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
vtable_slots++;
if (ARCH_USE_IMT) {
vtable_size = MONO_SIZEOF_VTABLE + vtable_slots * sizeof (gpointer);
if (class->interface_offsets_count) {
imt_table_bytes = sizeof (gpointer) * (MONO_IMT_SIZE);
vtable_size += sizeof (gpointer) * (MONO_IMT_SIZE);
mono_stats.imt_number_of_tables++;
mono_stats.imt_tables_size += (sizeof (gpointer) * MONO_IMT_SIZE);
mono_stats.imt_tables_size += imt_table_bytes;
} else {
imt_table_bytes = 0;
}
} else {
vtable_size = sizeof (gpointer) * (class->max_interface_id + 1) +
MONO_SIZEOF_VTABLE + vtable_slots * sizeof (gpointer);
imt_table_bytes = sizeof (gpointer) * (class->max_interface_id + 1);
}
vtable_size = imt_table_bytes + MONO_SIZEOF_VTABLE + vtable_slots * sizeof (gpointer);
mono_stats.used_class_count++;
mono_stats.class_vtable_size += vtable_size;
interface_offsets = mono_domain_alloc0 (domain, vtable_size);
if (ARCH_USE_IMT)
interface_offsets = alloc_vtable (domain, vtable_size, imt_table_bytes);
vt = (MonoVTable*) ((char*)interface_offsets + imt_table_bytes);
else
vt = (MonoVTable*) (interface_offsets + class->max_interface_id + 1);
g_assert (!((gsize)vt & 7));
vt->klass = class;
vt->rank = class->rank;
vt->domain = domain;
@ -2220,6 +2238,7 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
gpointer *interface_offsets;
uint8_t *bitmap;
int bsize;
size_t imt_table_bytes;
#ifdef COMPRESSED_INTERFACE_BITMAP
int bcsize;
@ -2266,22 +2285,21 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
}
if (ARCH_USE_IMT) {
imt_table_bytes = sizeof (gpointer) * MONO_IMT_SIZE;
mono_stats.imt_number_of_tables++;
mono_stats.imt_tables_size += (sizeof (gpointer) * MONO_IMT_SIZE);
vtsize = sizeof (gpointer) * (MONO_IMT_SIZE) +
MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
mono_stats.imt_tables_size += imt_table_bytes;
} else {
vtsize = sizeof (gpointer) * (max_interface_id + 1) +
MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
imt_table_bytes = sizeof (gpointer) * (max_interface_id + 1);
}
vtsize = imt_table_bytes + MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
mono_stats.class_vtable_size += vtsize + extra_interface_vtsize;
interface_offsets = mono_domain_alloc0 (domain, vtsize + extra_interface_vtsize);
if (ARCH_USE_IMT)
pvt = (MonoVTable*) (interface_offsets + MONO_IMT_SIZE);
else
pvt = (MonoVTable*) (interface_offsets + max_interface_id + 1);
interface_offsets = alloc_vtable (domain, vtsize + extra_interface_vtsize, imt_table_bytes);
pvt = (MonoVTable*) ((char*)interface_offsets + imt_table_bytes);
g_assert (!((gsize)pvt & 7));
memcpy (pvt, vt, MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer));
pvt->klass = mono_defaults.transparent_proxy_class;
@ -2775,8 +2793,10 @@ mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
#endif
{
if (method->is_inflated) {
MonoError error;
/* Have to inflate the result */
res = mono_class_inflate_generic_method (res, &((MonoMethodInflated*)method)->context);
res = mono_class_inflate_generic_method_checked (res, &((MonoMethodInflated*)method)->context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
}
@ -3234,7 +3254,7 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
}
/* MONO_TYPE_PTR is passed by value to runtime_invoke () */
args [0] = *ptr;
args [0] = ptr ? *ptr : NULL;
args [1] = mono_type_get_object (mono_domain_get (), type);
return mono_runtime_invoke (m, NULL, args, NULL);
@ -4368,7 +4388,6 @@ static inline void *
mono_object_allocate (size_t size, MonoVTable *vtable)
{
MonoObject *o;
mono_stats.new_object_count++;
ALLOC_OBJECT (o, vtable, size);
return o;
@ -4385,7 +4404,6 @@ static inline void *
mono_object_allocate_ptrfree (size_t size, MonoVTable *vtable)
{
MonoObject *o;
mono_stats.new_object_count++;
ALLOC_PTRFREE (o, vtable, size);
return o;
}
@ -4395,7 +4413,6 @@ mono_object_allocate_spec (size_t size, MonoVTable *vtable)
{
void *o;
ALLOC_TYPED (o, size, vtable);
mono_stats.new_object_count++;
return o;
}
@ -4416,7 +4433,6 @@ mono_object_new (MonoDomain *domain, MonoClass *klass)
{
MonoVTable *vtable;
MONO_ARCH_SAVE_REGS;
vtable = mono_class_vtable (domain, klass);
if (!vtable)
return NULL;
@ -4434,7 +4450,6 @@ mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
{
MonoVTable *vtable;
MONO_ARCH_SAVE_REGS;
vtable = mono_class_vtable (domain, klass);
if (!vtable)
return NULL;
@ -4458,8 +4473,6 @@ mono_object_new_specific (MonoVTable *vtable)
{
MonoObject *o;
MONO_ARCH_SAVE_REGS;
/* check for is_com_object for COM Interop */
if (mono_vtable_is_remote (vtable) || mono_class_is_com_object (vtable->klass))
{
@ -4662,8 +4675,6 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest)
uintptr_t size;
MonoClass *klass = src->obj.vtable->klass;
MONO_ARCH_SAVE_REGS;
g_assert (klass == dest->obj.vtable->klass);
size = mono_array_length (src);
@ -4699,8 +4710,6 @@ mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
uintptr_t *sizes;
MonoClass *klass = array->obj.vtable->klass;
MONO_ARCH_SAVE_REGS;
if (array->bounds == NULL) {
size = mono_array_length (array);
o = mono_array_new_full (domain, klass, &size, NULL);
@ -4879,7 +4888,6 @@ mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *leng
else
o = mono_gc_alloc_vector (vtable, byte_len, len);
array = (MonoArray*)o;
mono_stats.new_object_count++;
bounds = array->bounds;
#endif
@ -4911,8 +4919,6 @@ mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
{
MonoClass *ac;
MONO_ARCH_SAVE_REGS;
ac = mono_array_class_get (eclass, 1);
g_assert (ac);
@ -4934,8 +4940,6 @@ mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
MonoArray *ao;
uintptr_t byte_len;
MONO_ARCH_SAVE_REGS;
if (G_UNLIKELY (n > MONO_ARRAY_MAX_INDEX)) {
arith_overflow ();
return NULL;
@ -4964,7 +4968,6 @@ mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
#else
o = mono_gc_alloc_vector (vtable, byte_len, n);
ao = (MonoArray*)o;
mono_stats.new_object_count++;
#endif
if (G_UNLIKELY (profile_allocs))
@ -5041,10 +5044,10 @@ mono_string_new_size (MonoDomain *domain, gint32 len)
size_t size;
/* check for overflow */
if (len < 0 || len > ((SIZE_MAX - sizeof (MonoString) - 2) / 2))
if (len < 0 || len > ((SIZE_MAX - G_STRUCT_OFFSET (MonoString, chars) - 8) / 2))
mono_gc_out_of_memory (-1);
size = (sizeof (MonoString) + ((len + 1) * 2));
size = (G_STRUCT_OFFSET (MonoString, chars) + (((size_t)len + 1) * 2));
g_assert (size > 0);
vtable = mono_class_vtable (domain, mono_defaults.string_class);
@ -5151,8 +5154,6 @@ mono_string_new_wrapper (const char *text)
{
MonoDomain *domain = mono_domain_get ();
MONO_ARCH_SAVE_REGS;
if (text)
return mono_string_new (domain, text);
@ -5528,8 +5529,6 @@ mono_string_intern (MonoString *str)
MonoString*
mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
{
MONO_ARCH_SAVE_REGS;
if (image->dynamic) {
MonoString *str = mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
return str;

View File

@ -196,6 +196,9 @@ mono_monitor_try_enter (MonoObject *obj, uint32_t ms);
MONO_API mono_bool
mono_monitor_enter (MonoObject *obj);
MONO_API void
mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken);
MONO_API unsigned int
mono_object_get_size (MonoObject *o);

View File

@ -27,6 +27,7 @@
#include <mono/metadata/marshal.h>
#include "mono/utils/mono-digest.h"
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-counters.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
@ -359,11 +360,13 @@ dump_verify_info (MonoImage *image, int flags)
for (i = 0; i < m->rows; ++i) {
MonoMethod *method;
MonoError error;
mono_loader_clear_error ();
method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i+1), NULL);
method = mono_get_method_checked (image, MONO_TOKEN_METHOD_DEF | (i+1), NULL, NULL, &error);
if (!method) {
g_print ("Warning: Cannot lookup method with token 0x%08x\n", i + 1);
g_print ("Warning: Cannot lookup method with token 0x%08x due to %s\n", i + 1, mono_error_get_message (&error));
mono_error_cleanup (&error);
continue;
}
errors = mono_method_verify (method, flags);
@ -473,10 +476,12 @@ verify_image_file (const char *fname)
table = &image->tables [MONO_TABLE_TYPEDEF];
for (i = 1; i <= table->rows; ++i) {
MonoError error;
guint32 token = i | MONO_TOKEN_TYPE_DEF;
MonoClass *class = mono_class_get (image, token);
MonoClass *class = mono_class_get_checked (image, token, &error);
if (!class) {
printf ("Could not load class with token %x\n", token);
printf ("Could not load class with token %x due to %s\n", token, mono_error_get_message (&error));
mono_error_cleanup (&error);
continue;
}
mono_class_init (class);
@ -653,6 +658,7 @@ main (int argc, char *argv [])
#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters_init ();
#endif
mono_counters_init ();
mono_metadata_init ();
mono_images_init ();
mono_assemblies_init ();

View File

@ -34,8 +34,6 @@ HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
{
HANDLE handle;
MONO_ARCH_SAVE_REGS;
/* GetCurrentProcess returns a pseudo-handle, so use
* OpenProcess instead
*/
@ -52,16 +50,12 @@ HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
guint32
ves_icall_System_Diagnostics_Process_GetPid_internal (void)
{
MONO_ARCH_SAVE_REGS;
return mono_process_current_pid ();
}
void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *this,
HANDLE process)
{
MONO_ARCH_SAVE_REGS;
#ifdef THREAD_DEBUG
g_message ("%s: Closing process %p, handle %p", __func__, this, process);
#endif
@ -264,11 +258,11 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename)
process_set_field_int (filever, "productbuildpart", HIWORD (ffi->dwProductVersionLS));
process_set_field_int (filever, "productprivatepart", LOWORD (ffi->dwProductVersionLS));
process_set_field_bool (filever, "isdebug", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_DEBUG);
process_set_field_bool (filever, "isprerelease", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRERELEASE);
process_set_field_bool (filever, "ispatched", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PATCHED);
process_set_field_bool (filever, "isprivatebuild", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRIVATEBUILD);
process_set_field_bool (filever, "isspecialbuild", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_SPECIALBUILD);
process_set_field_bool (filever, "isdebug", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_DEBUG) != 0);
process_set_field_bool (filever, "isprerelease", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRERELEASE) != 0);
process_set_field_bool (filever, "ispatched", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PATCHED) != 0);
process_set_field_bool (filever, "isprivatebuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRIVATEBUILD) != 0);
process_set_field_bool (filever, "isspecialbuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_SPECIALBUILD) != 0);
}
g_free (query);
@ -356,9 +350,9 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename)
}
}
static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename)
static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class)
{
MonoClass *proc_class, *filever_class;
MonoClass *filever_class;
MonoObject *item, *filever;
MonoDomain *domain=mono_domain_get ();
MODULEINFO modinfo;
@ -366,8 +360,6 @@ static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *f
/* Build a System.Diagnostics.ProcessModule with the data.
*/
proc_class=mono_class_from_name (system_assembly, "System.Diagnostics",
"ProcessModule");
item=mono_object_new (domain, proc_class);
filever_class=mono_class_from_name (system_assembly,
@ -409,17 +401,19 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject
DWORD needed;
guint32 count = 0;
guint32 i, num_added = 0;
MonoClass *proc_class;
STASH_SYS_ASS (this);
if (EnumProcessModules (process, mods, sizeof(mods), &needed)) {
count = needed / sizeof(HMODULE);
temp_arr = mono_array_new (mono_domain_get (), mono_get_object_class (), count);
proc_class = mono_class_from_name (system_assembly, "System.Diagnostics", "ProcessModule");
temp_arr = mono_array_new (mono_domain_get (), proc_class, count);
for (i = 0; i < count; i++) {
if (GetModuleBaseName (process, mods[i], modname, MAX_PATH) &&
GetModuleFileNameEx (process, mods[i], filename, MAX_PATH)) {
MonoObject *module = process_add_module (process, mods[i],
filename, modname);
filename, modname, proc_class);
mono_array_setref (temp_arr, num_added++, module);
}
}
@ -429,7 +423,7 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject
arr = temp_arr;
} else {
/* shorter version of the array */
arr = mono_array_new (mono_domain_get (), mono_get_object_class (), num_added);
arr = mono_array_new (mono_domain_get (), proc_class, num_added);
for (i = 0; i < num_added; i++)
mono_array_setref (arr, i, mono_array_get (temp_arr, MonoObject*, i));
@ -440,8 +434,6 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject
void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this, MonoString *filename)
{
MONO_ARCH_SAVE_REGS;
STASH_SYS_ASS (this);
process_get_fileversion (this, mono_string_chars (filename));
@ -700,8 +692,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObjec
{
guint32 ret;
MONO_ARCH_SAVE_REGS;
if(ms<0) {
/* Wait forever */
ret=WaitForSingleObjectEx (process, INFINITE, TRUE);
@ -719,8 +709,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForInputIdle_internal (Mono
{
guint32 ret;
MONO_ARCH_SAVE_REGS;
if(ms<0) {
/* Wait forever */
ret=WaitForInputIdle (process, INFINITE);
@ -742,8 +730,6 @@ gint64 ves_icall_System_Diagnostics_Process_ExitTime_internal (HANDLE process)
gboolean ret;
FILETIME create_time, exit_time, kernel_time, user_time;
MONO_ARCH_SAVE_REGS;
ret = GetProcessTimes (process, &create_time, &exit_time, &kernel_time,
&user_time);
if (ret)
@ -757,8 +743,6 @@ gint64 ves_icall_System_Diagnostics_Process_StartTime_internal (HANDLE process)
gboolean ret;
FILETIME create_time, exit_time, kernel_time, user_time;
MONO_ARCH_SAVE_REGS;
ret = GetProcessTimes (process, &create_time, &exit_time, &kernel_time,
&user_time);
if (ret)
@ -771,8 +755,6 @@ gint32 ves_icall_System_Diagnostics_Process_ExitCode_internal (HANDLE process)
{
DWORD code;
MONO_ARCH_SAVE_REGS;
GetExitCodeProcess (process, &code);
LOGDEBUG (g_message ("%s: process exit code is %d", __func__, code));
@ -789,8 +771,6 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr
DWORD needed;
guint32 len;
MONO_ARCH_SAVE_REGS;
ok=EnumProcessModules (process, &mod, sizeof(mod), &needed);
if(ok==FALSE) {
return(NULL);
@ -809,18 +789,19 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr
}
/* Returns an array of pids */
MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
MonoArray *
ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
{
#if !defined(HOST_WIN32)
MonoArray *procs;
gpointer *pidarray;
int i, count;
MONO_ARCH_SAVE_REGS;
pidarray = mono_process_list (&count);
if (!pidarray)
mono_raise_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses"));
if (!pidarray) {
mono_set_pending_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses"));
return NULL;
}
procs = mono_array_new (mono_domain_get (), mono_get_int32_class (), count);
if (sizeof (guint32) == sizeof (gpointer)) {
memcpy (mono_array_addr (procs, guint32, 0), pidarray, count);
@ -848,8 +829,8 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
g_free (pids);
pids = NULL;
exc = mono_get_exception_not_supported ("This system does not support EnumProcesses");
mono_raise_exception (exc);
g_assert_not_reached ();
mono_set_pending_exception (exc);
return NULL;
}
if (needed < (count * sizeof (guint32)))
break;
@ -873,8 +854,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_GetWorkingSet_internal (HANDLE
gboolean ret;
SIZE_T ws_min, ws_max;
MONO_ARCH_SAVE_REGS;
ret=GetProcessWorkingSetSize (process, &ws_min, &ws_max);
*min=(guint32)ws_min;
*max=(guint32)ws_max;
@ -888,8 +867,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_SetWorkingSet_internal (HANDLE
SIZE_T ws_min;
SIZE_T ws_max;
MONO_ARCH_SAVE_REGS;
ret=GetProcessWorkingSetSize (process, &ws_min, &ws_max);
if(ret==FALSE) {
return(FALSE);
@ -909,8 +886,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_SetWorkingSet_internal (HANDLE
MonoBoolean
ves_icall_System_Diagnostics_Process_Kill_internal (HANDLE process, gint32 sig)
{
MONO_ARCH_SAVE_REGS;
/* sig == 1 -> Kill, sig == 2 -> CloseMainWindow */
return TerminateProcess (process, -sig);
@ -956,8 +931,6 @@ ves_icall_System_Diagnostics_Process_ProcessHandle_duplicate (HANDLE process)
{
HANDLE ret;
MONO_ARCH_SAVE_REGS;
LOGDEBUG (g_message ("%s: Duplicating process handle %p", __func__, process));
DuplicateHandle (GetCurrentProcess (), process, GetCurrentProcess (),
@ -969,8 +942,6 @@ ves_icall_System_Diagnostics_Process_ProcessHandle_duplicate (HANDLE process)
void
ves_icall_System_Diagnostics_Process_ProcessHandle_close (HANDLE process)
{
MONO_ARCH_SAVE_REGS;
LOGDEBUG (g_message ("%s: Closing process handle %p", __func__, process));
CloseHandle (process);

View File

@ -73,7 +73,7 @@ void mono_profiler_gc_roots (int num, void **objects, int *root_types, uin
void mono_profiler_code_chunk_new (gpointer chunk, int size) MONO_INTERNAL;
void mono_profiler_code_chunk_destroy (gpointer chunk) MONO_INTERNAL;
void mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, void *data) MONO_INTERNAL;
void mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, gconstpointer data) MONO_INTERNAL;
void mono_profiler_runtime_initialized (void) MONO_INTERNAL;

View File

@ -936,11 +936,11 @@ mono_profiler_install_iomap (MonoProfileIomapFunc callback)
}
void
mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, void *data) {
mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, gconstpointer data) {
ProfilerDesc *prof;
for (prof = prof_list; prof; prof = prof->next) {
if (prof->code_buffer_new)
prof->code_buffer_new (prof->profiler, buffer, size, type, data);
prof->code_buffer_new (prof->profiler, buffer, size, type, (void*)data);
}
}

View File

@ -65,6 +65,14 @@ typedef struct {
typedef enum {
MONO_PROFILER_CODE_BUFFER_UNKNOWN,
MONO_PROFILER_CODE_BUFFER_METHOD,
MONO_PROFILER_CODE_BUFFER_METHOD_TRAMPOLINE,
MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE,
MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE,
MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE,
MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE,
MONO_PROFILER_CODE_BUFFER_HELPER,
MONO_PROFILER_CODE_BUFFER_MONITOR,
MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE,
MONO_PROFILER_CODE_BUFFER_LAST
} MonoProfilerCodeBufferType;

View File

@ -26,7 +26,7 @@
#include <mono/metadata/rand.h>
#include <mono/metadata/exception.h>
#if !defined(__native_client__) && !defined(HOST_WIN32)
#if !defined(__native_client__) && !defined(HOST_WIN32) && defined (HAVE_SYS_UN_H)
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
@ -180,7 +180,7 @@ ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngClose (gpoint
CryptReleaseContext ((HCRYPTPROV) handle, 0);
}
#elif defined (__native_client__)
#elif defined (__native_client__) || !defined (HAVE_SYS_UN_H)
#include <time.h>

View File

@ -2866,6 +2866,7 @@ mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCto
static MonoMethod*
mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m)
{
MonoError error;
MonoClass *klass;
MonoGenericContext tmp_context;
MonoType **type_argv;
@ -2898,7 +2899,8 @@ mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderI
tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
tmp_context.method_inst = ginst;
inflated = mono_class_inflate_generic_method (method, &tmp_context);
inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
return inflated;
}
@ -4768,8 +4770,6 @@ mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
char buf [16];
char *b = buf;
MONO_ARCH_SAVE_REGS;
if (!module->dynamic_image)
mono_image_module_basic_init (module);
@ -5287,8 +5287,6 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
MonoDynamicImage *image;
MonoDomain *domain = mono_object_domain (assemblyb);
MONO_ARCH_SAVE_REGS;
if (assemblyb->dynamic_assembly)
return;
@ -7356,6 +7354,7 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
g_ptr_array_add (info->type_arguments, subinfo);
while (*p == ' ') p++;
if (*p == '[') {
p++;
fqname = TRUE;
@ -9887,8 +9886,6 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
char *buffer, *p;
guint32 buflen, i;
MONO_ARCH_SAVE_REGS;
if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
/* sig is freed later so allocate it in the heap */
sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor);
@ -9966,8 +9963,6 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
MonoError error;
MonoClass *klass, *parent;
MONO_ARCH_SAVE_REGS;
RESOLVE_TYPE (tb->parent);
mono_loader_lock ();
@ -10105,8 +10100,6 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
MonoClass *klass;
int count, i;
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (tb->type.type);
count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
@ -10150,8 +10143,6 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
{
MonoClass *klass;
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (tb->type.type);
mono_loader_lock ();
@ -10695,6 +10686,7 @@ mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **
MonoReflectionMethod*
mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
{
MonoError error;
MonoClass *klass;
MonoMethod *method, *inflated;
MonoMethodInflated *imethod;
@ -10703,8 +10695,6 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
MonoType **type_argv;
int count, i;
MONO_ARCH_SAVE_REGS;
/*FIXME but this no longer should happen*/
if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
#ifndef DISABLE_REFLECTION_EMIT
@ -10745,7 +10735,8 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
tmp_context.method_inst = ginst;
inflated = mono_class_inflate_generic_method (method, &tmp_context);
inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
imethod = (MonoMethodInflated *) inflated;
/*FIXME but I think this is no longer necessary*/
@ -10795,7 +10786,9 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
g_assert (i < klass->method.count);
imethod = (MonoMethodInflated*)klass->methods [i];
} else {
imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context);
MonoError error;
imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
if (method->is_generic && image_is_dynamic (method->klass->image)) {
@ -10855,8 +10848,6 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
MonoType *gtype;
int i;
MONO_ARCH_SAVE_REGS;
gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type);
klass = mono_class_from_mono_type (gtype);
g_assert (gtype->type == MONO_TYPE_GENERICINST);
@ -10966,8 +10957,10 @@ fix_partial_generic_class (MonoClass *klass)
klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
for (i = 0; i < klass->method.count; i++) {
klass->methods [i] = mono_class_inflate_generic_method_full (
gklass->methods [i], klass, mono_class_get_context (klass));
MonoError error;
klass->methods [i] = mono_class_inflate_generic_method_full_checked (
gklass->methods [i], klass, mono_class_get_context (klass), &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
}
@ -11186,8 +11179,8 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
mono_error_init (error);
if (tb->class_size) {
if ((tb->packing_size & 0xfffffff0) != 0) {
char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", klass->name, tb->packing_size);
if ((tb->packing_size & 0xffffff00) != 0) {
char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
return;
}
@ -11428,8 +11421,6 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
MonoReflectionType* res;
int i, j;
MONO_ARCH_SAVE_REGS;
domain = mono_object_domain (tb);
klass = mono_class_from_mono_type (tb->type.type);
@ -11606,8 +11597,6 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
MonoClass *pklass;
MonoError error;
MONO_ARCH_SAVE_REGS;
image = &gparam->tbuilder->module->dynamic_image->image;
param = mono_image_new0 (image, MonoGenericParamFull, 1);
@ -11847,16 +11836,18 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
}
MonoMethodSignature *
mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token)
mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
{
MonoMethodSignature *sig;
g_assert (image_is_dynamic (image));
mono_error_init (error);
sig = g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
if (sig)
return sig;
return mono_method_signature (method);
return mono_method_signature_checked (method, error);
}
#ifndef DISABLE_REFLECTION_EMIT
@ -11950,8 +11941,11 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
result = ((MonoReflectionMethod*)obj)->method;
if (context)
result = mono_class_inflate_generic_method (result, context);
if (context) {
MonoError error;
result = mono_class_inflate_generic_method_checked (result, context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
*handle_class = mono_defaults.methodhandle_class;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
@ -11973,8 +11967,11 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
*/
result = mb->mhandle;
}
if (context)
result = mono_class_inflate_generic_method (result, context);
if (context) {
MonoError error;
result = mono_class_inflate_generic_method_checked (result, context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
@ -11986,8 +11983,11 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
result = cb->mhandle;
}
if (context)
result = mono_class_inflate_generic_method (result, context);
if (context) {
MonoError error;
result = mono_class_inflate_generic_method_checked (result, context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
MonoClassField *field = ((MonoReflectionField*)obj)->field;
@ -12139,8 +12139,11 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
if (m->method_args) {
result = mono_reflection_method_on_tb_inst_get_handle (m);
if (context)
result = mono_class_inflate_generic_method (result, context);
if (context) {
MonoError error;
result = mono_class_inflate_generic_method_checked (result, context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
}
} else {
MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context);
MonoClass *inflated_klass = mono_class_from_mono_type (type);

2008
mta-mono/vendor/mono/metadata/remoting.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
/*
* remoting.h: Remoting support
*
* (C) 2014 Xamarin, Inc. http://www.xamarin.com
*
*/
#ifndef __MONO_REMOTING_H__
#define __MONO_REMOTING_H__
#include "config.h"
#include <mono/metadata/class.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/class-internals.h>
void mono_remoting_init (void) MONO_INTERNAL;
#ifndef DISABLE_REMOTING
MonoMethod *
mono_marshal_get_remoting_invoke (MonoMethod *method) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_xappdomain_invoke (MonoMethod *method) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_remoting_invoke_for_target (MonoMethod *method, MonoRemotingTarget target_type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_stfld_wrapper (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_ldfld_wrapper (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_ldflda_wrapper (MonoType *type) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_stfld_remote_wrapper (MonoClass *klass) MONO_INTERNAL;
MonoMethod *
mono_marshal_get_proxy_cancast (MonoClass *klass) MONO_INTERNAL;
#endif
#endif

View File

@ -119,8 +119,6 @@ mono_runtime_try_shutdown (void)
gboolean
mono_runtime_is_critical_method (MonoMethod *method)
{
if (mono_monitor_is_il_fastpath_wrapper (method))
return TRUE;
return FALSE;
}

View File

@ -51,7 +51,6 @@
#define ALIGN_UP SGEN_ALIGN_UP
#define ALLOC_ALIGN SGEN_ALLOC_ALIGN
#define ALLOC_ALIGN_BITS SGEN_ALLOC_ALIGN_BITS
#define MAX_SMALL_OBJ_SIZE SGEN_MAX_SMALL_OBJ_SIZE
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
@ -68,9 +67,9 @@ enum {
static gboolean use_managed_allocator = TRUE;
#ifdef HEAVY_STATISTICS
static long long stat_objects_alloced = 0;
static long long stat_bytes_alloced = 0;
static long long stat_bytes_alloced_los = 0;
static guint64 stat_objects_alloced = 0;
static guint64 stat_bytes_alloced = 0;
static guint64 stat_bytes_alloced_los = 0;
#endif
@ -94,7 +93,7 @@ static __thread char *tlab_next;
static __thread char *tlab_temp_end;
static __thread char *tlab_real_end;
/* Used by the managed allocator/wbarrier */
static __thread char **tlab_next_addr;
static __thread char **tlab_next_addr MONO_ATTR_USED;
#endif
#ifdef HAVE_KW_THREAD
@ -188,8 +187,8 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
/* FIXME: handle OOM */
void **p;
char *new_next;
TLAB_ACCESS_INIT;
size_t real_size = size;
TLAB_ACCESS_INIT;
CANARIFY_SIZE(size);
@ -291,20 +290,31 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
available_in_tlab = (int)(TLAB_REAL_END - TLAB_NEXT);//We'll never have tlabs > 2Gb
if (size > tlab_size || available_in_tlab > SGEN_MAX_NURSERY_WASTE) {
/* Allocate directly from the nursery */
do {
p = sgen_nursery_alloc (size);
if (!p) {
/*
* We couldn't allocate from the nursery, so we try
* collecting. Even after the collection, we might
* still not have enough memory to allocate the
* object. The reason will most likely be that we've
* run out of memory, but there is the theoretical
* possibility that other threads might have consumed
* the freed up memory ahead of us.
*
* What we do in this case is allocate degraded, i.e.,
* from the major heap.
*
* Ideally we'd like to detect the case of other
* threads allocating ahead of us and loop (if we
* always loop we will loop endlessly in the case of
* OOM).
*/
sgen_ensure_free_space (real_size);
if (degraded_mode)
return alloc_degraded (vtable, size, FALSE);
else
if (!degraded_mode)
p = sgen_nursery_alloc (size);
}
} while (!p);
if (!p) {
// no space left
g_assert (0);
}
if (!p)
return alloc_degraded (vtable, size, FALSE);
zero_tlab_if_necessary (p, size);
} else {
@ -313,21 +323,15 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
SGEN_LOG (3, "Retire TLAB: %p-%p [%ld]", TLAB_START, TLAB_REAL_END, (long)(TLAB_REAL_END - TLAB_NEXT - size));
sgen_nursery_retire_region (p, available_in_tlab);
do {
p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
if (!p) {
/* See comment above in similar case. */
sgen_ensure_free_space (tlab_size);
if (degraded_mode)
return alloc_degraded (vtable, size, FALSE);
else
if (!degraded_mode)
p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
}
} while (!p);
if (!p) {
// no space left
g_assert (0);
}
if (!p)
return alloc_degraded (vtable, size, FALSE);
/* Allocate a new TLAB from the current nursery fragment */
TLAB_START = (char*)p;
@ -374,8 +378,8 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size)
{
void **p;
char *new_next;
TLAB_ACCESS_INIT;
size_t real_size = size;
TLAB_ACCESS_INIT;
CANARIFY_SIZE(size);
@ -520,7 +524,7 @@ mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
/*This doesn't require fencing since EXIT_CRITICAL_REGION already does it for us*/
arr->max_length = (mono_array_size_t)max_length;
EXIT_CRITICAL_REGION;
return arr;
goto done;
}
EXIT_CRITICAL_REGION;
#endif
@ -535,8 +539,11 @@ mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
arr->max_length = (mono_array_size_t)max_length;
UNLOCK_GC;
done:
SGEN_ASSERT (6, SGEN_ALIGN_UP (size) == SGEN_ALIGN_UP (sgen_par_object_get_size (vtable, (MonoObject*)arr)), "Vector has incorrect size.");
return arr;
}
@ -560,7 +567,7 @@ mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uint
bounds = (MonoArrayBounds*)((char*)arr + size - bounds_size);
arr->bounds = bounds;
EXIT_CRITICAL_REGION;
return arr;
goto done;
}
EXIT_CRITICAL_REGION;
#endif
@ -580,6 +587,8 @@ mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uint
UNLOCK_GC;
done:
SGEN_ASSERT (6, SGEN_ALIGN_UP (size) == SGEN_ALIGN_UP (sgen_par_object_get_size (vtable, (MonoObject*)arr)), "Array has incorrect size.");
return arr;
}
@ -774,7 +783,7 @@ create_allocator (int atype)
}
if (atype == ATYPE_SMALL) {
num_params = 1;
num_params = 2;
name = "AllocSmall";
} else if (atype == ATYPE_NORMAL) {
num_params = 1;
@ -804,7 +813,11 @@ create_allocator (int atype)
#ifndef DISABLE_JIT
size_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
if (atype == ATYPE_NORMAL || atype == ATYPE_SMALL) {
if (atype == ATYPE_SMALL) {
/* size_var = size_arg */
mono_mb_emit_ldarg (mb, 1);
mono_mb_emit_stloc (mb, size_var);
} else if (atype == ATYPE_NORMAL) {
/* size = vtable->klass->instance_size; */
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoVTable, klass));
@ -896,7 +909,7 @@ create_allocator (int atype)
/*
* a string allocator method takes the args: (vtable, len)
*
* bytes = sizeof (MonoString) + ((len + 1) * 2)
* bytes = offsetof (MonoString, chars) + ((len + 1) * 2)
*
* condition:
*
@ -904,11 +917,11 @@ create_allocator (int atype)
*
* therefore:
*
* sizeof (MonoString) + ((len + 1) * 2) <= INT32_MAX - (SGEN_ALLOC_ALIGN - 1)
* len <= (INT32_MAX - (SGEN_ALLOC_ALIGN - 1) - sizeof (MonoString)) / 2 - 1
* offsetof (MonoString, chars) + ((len + 1) * 2) <= INT32_MAX - (SGEN_ALLOC_ALIGN - 1)
* len <= (INT32_MAX - (SGEN_ALLOC_ALIGN - 1) - offsetof (MonoString, chars)) / 2 - 1
*/
mono_mb_emit_ldarg (mb, 1);
mono_mb_emit_icon (mb, (INT32_MAX - (SGEN_ALLOC_ALIGN - 1) - sizeof (MonoString)) / 2 - 1);
mono_mb_emit_icon (mb, (INT32_MAX - (SGEN_ALLOC_ALIGN - 1) - MONO_STRUCT_OFFSET (MonoString, chars)) / 2 - 1);
pos = mono_mb_emit_short_branch (mb, MONO_CEE_BLE_UN_S);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
@ -920,13 +933,14 @@ create_allocator (int atype)
mono_mb_emit_icon (mb, 1);
mono_mb_emit_byte (mb, MONO_CEE_SHL);
//WE manually fold the above + 2 here
mono_mb_emit_icon (mb, sizeof (MonoString) + 2);
mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoString, chars) + 2);
mono_mb_emit_byte (mb, CEE_ADD);
mono_mb_emit_stloc (mb, size_var);
} else {
g_assert_not_reached ();
}
if (atype != ATYPE_SMALL) {
/* size += ALLOC_ALIGN - 1; */
mono_mb_emit_ldloc (mb, size_var);
mono_mb_emit_icon (mb, ALLOC_ALIGN - 1);
@ -935,6 +949,7 @@ create_allocator (int atype)
mono_mb_emit_icon (mb, ~(ALLOC_ALIGN - 1));
mono_mb_emit_byte (mb, CEE_AND);
mono_mb_emit_stloc (mb, size_var);
}
/* if (size > MAX_SMALL_OBJ_SIZE) goto slowpath */
if (atype != ATYPE_SMALL) {
@ -1006,8 +1021,9 @@ create_allocator (int atype)
mono_mb_emit_byte (mb, CEE_STIND_I);
/*The tlab store must be visible before the the vtable store. This could be replaced with a DDS but doing it with IL would be tricky. */
mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX);
mono_mb_emit_op (mb, CEE_MONO_MEMORY_BARRIER, (gpointer)StoreStoreBarrier);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_MEMORY_BARRIER);
mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_REL);
/* *p = vtable; */
mono_mb_emit_ldloc (mb, p_var);
@ -1045,8 +1061,9 @@ create_allocator (int atype)
/*
We must make sure both vtable and max_length are globaly visible before returning to managed land.
*/
mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX);
mono_mb_emit_op (mb, CEE_MONO_MEMORY_BARRIER, (gpointer)StoreStoreBarrier);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_MEMORY_BARRIER);
mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_REL);
/* return p */
mono_mb_emit_ldloc (mb, p_var);
@ -1066,13 +1083,22 @@ create_allocator (int atype)
}
#endif
int
mono_gc_get_aligned_size_for_allocator (int size)
{
int aligned_size = size;
aligned_size += ALLOC_ALIGN - 1;
aligned_size &= ~(ALLOC_ALIGN - 1);
return aligned_size;
}
/*
* Generate an allocator method implementing the fast path of mono_gc_alloc_obj ().
* The signature of the called method is:
* object allocate (MonoVTable *vtable)
*/
MonoMethod*
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size)
{
#ifdef MANAGED_ALLOCATION
@ -1091,6 +1117,8 @@ mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
return NULL;
if (klass->instance_size > tlab_size)
return NULL;
if (known_instance_size && ALIGN_TO (klass->instance_size, ALLOC_ALIGN) >= MAX_SMALL_OBJ_SIZE)
return NULL;
if (klass->has_finalize || mono_class_is_marshalbyref (klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
return NULL;
@ -1099,7 +1127,7 @@ mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
if (klass->byval_arg.type == MONO_TYPE_STRING)
return mono_gc_get_managed_allocator_by_type (ATYPE_STRING);
/* Generic classes have dynamic field and can go above MAX_SMALL_OBJ_SIZE. */
if (ALIGN_TO (klass->instance_size, ALLOC_ALIGN) < MAX_SMALL_OBJ_SIZE && !mono_class_is_open_constructed_type (&klass->byval_arg))
if (known_instance_size)
return mono_gc_get_managed_allocator_by_type (ATYPE_SMALL);
else
return mono_gc_get_managed_allocator_by_type (ATYPE_NORMAL);
@ -1209,9 +1237,9 @@ sgen_has_managed_allocator (void)
void
sgen_alloc_init_heavy_stats (void)
{
mono_counters_register ("# objects allocated", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_objects_alloced);
mono_counters_register ("bytes allocated", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_bytes_alloced);
mono_counters_register ("bytes allocated in LOS", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_bytes_alloced_los);
mono_counters_register ("# objects allocated", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_objects_alloced);
mono_counters_register ("bytes allocated", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_bytes_alloced);
mono_counters_register ("bytes allocated in LOS", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_bytes_alloced_los);
}
#endif

Some files were not shown because too many files have changed in this diff Show More