Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Toshok <toshok@novell.com>2010-02-17 02:06:33 +0300
committerChris Toshok <toshok@novell.com>2010-02-17 02:06:33 +0300
commit79e05e9d6f8eca93467f104aed4fc19733e909a7 (patch)
tree511d669d5bb4fb1cef183895a49214030b80de86
parentd8ba19059dc8da2af1b5c2447e3230162afdcd34 (diff)
merge -r151658:151801 from mono-2-6 branchmoon/2.99.0.3
svn path=/branches/moon-2-99-0-3/mono/; revision=151880
-rw-r--r--mono/metadata/ChangeLog5
-rw-r--r--mono/metadata/debug-helpers.c35
-rw-r--r--mono/mini/ChangeLog23
-rw-r--r--mono/mini/aot-compiler.c31
-rw-r--r--mono/mini/aot-runtime.c105
-rw-r--r--mono/mini/debugger-agent.c32
-rw-r--r--mono/mini/driver.c2
-rw-r--r--mono/mini/mini-arm.c26
-rw-r--r--mono/mini/mini.c20
-rw-r--r--mono/mini/mini.h3
-rw-r--r--mono/profiler/ChangeLog6
-rw-r--r--mono/profiler/mono-profiler-aot.c9
12 files changed, 274 insertions, 23 deletions
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
index 0dbd09498ba..16b1574c7d4 100644
--- a/mono/metadata/ChangeLog
+++ b/mono/metadata/ChangeLog
@@ -1,3 +1,8 @@
+2010-02-13 Zoltan Varga <vargaz@gmail.com>
+
+ * debug-helpers.c (mono_method_desc_search_in_image): Handle short names like
+ 'int' for system classes.
+
2010-01-16 Zoltan Varga <vargaz@gmail.com>
* generic-sharing.c (instantiate_other_info): Don't create ftnptr's from the
diff --git a/mono/metadata/debug-helpers.c b/mono/metadata/debug-helpers.c
index 58765ebf2f7..e1adb9d9dc7 100644
--- a/mono/metadata/debug-helpers.c
+++ b/mono/metadata/debug-helpers.c
@@ -86,6 +86,31 @@ append_class_name (GString *res, MonoClass *class, gboolean include_namespace)
g_string_append_printf (res, "%s", class->name);
}
+static MonoClass*
+find_system_class (const char *name)
+{
+ if (!strcmp (name, "void"))
+ return mono_defaults.void_class;
+ else if (!strcmp (name, "char")) return mono_defaults.char_class;
+ else if (!strcmp (name, "bool")) return mono_defaults.boolean_class;
+ else if (!strcmp (name, "byte")) return mono_defaults.byte_class;
+ else if (!strcmp (name, "sbyte")) return mono_defaults.sbyte_class;
+ else if (!strcmp (name, "uint16")) return mono_defaults.uint16_class;
+ else if (!strcmp (name, "int16")) return mono_defaults.int16_class;
+ else if (!strcmp (name, "uint")) return mono_defaults.uint32_class;
+ else if (!strcmp (name, "int")) return mono_defaults.int32_class;
+ else if (!strcmp (name, "ulong")) return mono_defaults.uint64_class;
+ else if (!strcmp (name, "long")) return mono_defaults.int64_class;
+ else if (!strcmp (name, "uintptr")) return mono_defaults.uint_class;
+ else if (!strcmp (name, "intptr")) return mono_defaults.int_class;
+ else if (!strcmp (name, "single")) return mono_defaults.single_class;
+ else if (!strcmp (name, "double")) return mono_defaults.double_class;
+ else if (!strcmp (name, "string")) return mono_defaults.string_class;
+ else if (!strcmp (name, "object")) return mono_defaults.object_class;
+ else
+ return NULL;
+}
+
void
mono_type_get_desc (GString *res, MonoType *type, gboolean include_namespace)
{
@@ -281,6 +306,9 @@ mono_method_desc_new (const char *name, gboolean include_namespace)
class_nspace = g_strdup (name);
use_args = strchr (class_nspace, '(');
if (use_args) {
+ /* Allow a ' ' between the method name and the signature */
+ if (use_args > class_nspace && use_args [-1] == ' ')
+ use_args [-1] = 0;
*use_args++ = 0;
end = strchr (use_args, ')');
if (!end) {
@@ -463,6 +491,13 @@ mono_method_desc_search_in_image (MonoMethodDesc *desc, MonoImage *image)
MonoMethod *method;
int i;
+ /* Handle short names for system classes */
+ if (!desc->namespace && image == mono_defaults.corlib) {
+ klass = find_system_class (desc->klass);
+ if (klass)
+ return mono_method_desc_search_in_class (desc, klass);
+ }
+
if (desc->namespace && desc->klass) {
klass = mono_class_from_name (image, desc->namespace, desc->klass);
if (!klass)
diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog
index 997c4c7ec19..12fdc80b6b1 100644
--- a/mono/mini/ChangeLog
+++ b/mono/mini/ChangeLog
@@ -1,3 +1,26 @@
+2010-02-13 Zoltan Varga <vargaz@gmail.com>
+
+ * aot-compiler.c (load_profile_files): Update after the profiler changes.
+
+2010-02-13 Zoltan Varga <vargaz@gmail.com>
+
+ * mini.c (mono_jit_compile_method_inner): Avoid passing icall wrappers to
+ mono_profiler_method_end_jit, since the profiler has no way to process wrappers.
+
+ * aot-runtime.c mini.c: Resurrect the aot pagefault profiling stuff, it is useful
+ for mtouch.
+
+2010-02-13 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+ * debugger-agent.c: handle incomplete reads and EINTR in
+ recv()/send(). This could have been causing random
+ disconnections.
+
+2010-02-13 Zoltan Varga <vargaz@gmail.com>
+
+ * mini-arm.c (mono_arch_allocate_vars): Allocate the seq point related vars first
+ so they have small offsets. Fixes #566311.
+
2010-02-12 Rodrigo Kumpera <rkumpera@novell.com>
* method-to-ir.c (mono_method_check_inlining): Check for loader errors.
diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c
index 4f7a0d47e49..20f488f94bc 100644
--- a/mono/mini/aot-compiler.c
+++ b/mono/mini/aot-compiler.c
@@ -3937,7 +3937,7 @@ load_profile_files (MonoAotCompile *acfg)
file_index = 0;
while (TRUE) {
- tmp = g_strdup_printf ("%s/.mono/aot-profile-data/%s-%s-%d", g_get_home_dir (), acfg->image->assembly_name, acfg->image->guid, file_index);
+ tmp = g_strdup_printf ("%s/.mono/aot-profile-data/%s-%d", g_get_home_dir (), acfg->image->assembly_name, file_index);
if (!g_file_test (tmp, G_FILE_TEST_IS_REGULAR)) {
g_free (tmp);
@@ -3953,21 +3953,38 @@ load_profile_files (MonoAotCompile *acfg)
file_index ++;
res = fscanf (infile, "%32s\n", ver);
- if ((res != 1) || strcmp (ver, "#VER:1") != 0) {
+ if ((res != 1) || strcmp (ver, "#VER:2") != 0) {
printf ("Profile file has wrong version or invalid.\n");
fclose (infile);
continue;
}
while (TRUE) {
- res = fscanf (infile, "%d\n", &token);
- if (res < 1)
+ char name [1024];
+ MonoMethodDesc *desc;
+ MonoMethod *method;
+
+ if (fgets (name, 1023, infile) == NULL)
break;
- method_index = mono_metadata_token_index (token) - 1;
+ /* Kill the newline */
+ if (strlen (name) > 0)
+ name [strlen (name) - 1] = '\0';
+
+ desc = mono_method_desc_new (name, TRUE);
+
+ method = mono_method_desc_search_in_image (desc, acfg->image);
+
+ if (method && mono_method_get_token (method)) {
+ token = mono_method_get_token (method);
+ method_index = mono_metadata_token_index (token) - 1;
- if (!g_list_find (acfg->method_order, GUINT_TO_POINTER (method_index)))
- acfg->method_order = g_list_append (acfg->method_order, GUINT_TO_POINTER (method_index));
+ if (!g_list_find (acfg->method_order, GUINT_TO_POINTER (method_index))) {
+ acfg->method_order = g_list_append (acfg->method_order, GUINT_TO_POINTER (method_index));
+ }
+ } else {
+ //printf ("No method found matching '%s'.\n", name);
+ }
}
fclose (infile);
}
diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c
index 9a7a5a6ff32..eae228bbc59 100644
--- a/mono/mini/aot-runtime.c
+++ b/mono/mini/aot-runtime.c
@@ -156,6 +156,7 @@ static gint32 mono_last_aot_method = -1;
static gboolean make_unreadable = FALSE;
static guint32 name_table_accesses = 0;
+static guint32 n_pagefaults = 0;
/* Used to speed-up find_aot_module () */
static gsize aot_code_low_addr = (gssize)-1;
@@ -1097,17 +1098,19 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
if (make_unreadable) {
#ifndef PLATFORM_WIN32
guint8 *addr;
- guint8 *page_start;
- int pages, err, len;
+ guint8 *page_start, *page_end;
+ int err, len;
addr = amodule->mem_begin;
len = amodule->mem_end - amodule->mem_begin;
/* Round down in both directions to avoid modifying data which is not ours */
page_start = (guint8 *) (((gssize) (addr)) & ~ (mono_pagesize () - 1)) + mono_pagesize ();
- pages = ((addr + len - page_start + mono_pagesize () - 1) / mono_pagesize ()) - 1;
- err = mono_mprotect (page_start, pages * mono_pagesize (), MONO_MMAP_NONE);
- g_assert (err == 0);
+ page_end = (guint8 *) (((gssize) (addr + len)) & ~ (mono_pagesize () - 1));
+ if (page_end > page_start) {
+ err = mono_mprotect (page_start, (page_end - page_start), MONO_MMAP_NONE);
+ g_assert (err == 0);
+ }
#endif
}
@@ -3053,6 +3056,98 @@ mono_aot_get_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem
return code;
}
+
+/*
+ * mono_aot_set_make_unreadable:
+ *
+ * Set whenever to make all mmaped memory unreadable. In conjuction with a
+ * SIGSEGV handler, this is useful to find out which pages the runtime tries to read.
+ */
+void
+mono_aot_set_make_unreadable (gboolean unreadable)
+{
+ static int inited;
+
+ make_unreadable = unreadable;
+
+ if (make_unreadable && !inited) {
+ mono_counters_register ("AOT pagefaults", MONO_COUNTER_JIT | MONO_COUNTER_INT, &n_pagefaults);
+ }
+}
+
+typedef struct {
+ MonoAotModule *module;
+ guint8 *ptr;
+} FindMapUserData;
+
+static void
+find_map (gpointer key, gpointer value, gpointer user_data)
+{
+ MonoAotModule *module = (MonoAotModule*)value;
+ FindMapUserData *data = (FindMapUserData*)user_data;
+
+ if (!data->module)
+ if ((data->ptr >= module->mem_begin) && (data->ptr < module->mem_end))
+ data->module = module;
+}
+
+static MonoAotModule*
+find_module_for_addr (void *ptr)
+{
+ FindMapUserData data;
+
+ if (!make_unreadable)
+ return NULL;
+
+ data.module = NULL;
+ data.ptr = (guint8*)ptr;
+
+ mono_aot_lock ();
+ g_hash_table_foreach (aot_modules, (GHFunc)find_map, &data);
+ mono_aot_unlock ();
+
+ return data.module;
+}
+
+/*
+ * mono_aot_is_pagefault:
+ *
+ * Should be called from a SIGSEGV signal handler to find out whenever @ptr is
+ * within memory allocated by this module.
+ */
+gboolean
+mono_aot_is_pagefault (void *ptr)
+{
+ if (!make_unreadable)
+ return FALSE;
+
+ /*
+ * Not signal safe, but SIGSEGV's are synchronous, and
+ * this is only turned on by a MONO_DEBUG option.
+ */
+ return find_module_for_addr (ptr) != NULL;
+}
+
+/*
+ * mono_aot_handle_pagefault:
+ *
+ * Handle a pagefault caused by an unreadable page by making it readable again.
+ */
+void
+mono_aot_handle_pagefault (void *ptr)
+{
+#ifndef PLATFORM_WIN32
+ guint8* start = (guint8*)ROUND_DOWN (((gssize)ptr), mono_pagesize ());
+ int res;
+
+ mono_aot_lock ();
+ res = mono_mprotect (start, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
+ g_assert (res == 0);
+
+ n_pagefaults ++;
+ mono_aot_unlock ();
+#endif
+}
#else
/* AOT disabled */
diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c
index 3cdcd535afe..d86929c489a 100644
--- a/mono/mini/debugger-agent.c
+++ b/mono/mini/debugger-agent.c
@@ -882,6 +882,24 @@ mono_debugger_agent_cleanup (void)
}
/*
+ * recv_length:
+ *
+ * recv() + handle incomplete reads and EINTR
+ */
+static int
+recv_length (int fd, void *buf, int len, int flags)
+{
+ int res;
+ int total = 0;
+
+ do {
+ res = recv (fd, (char *) buf + total, len - total, flags);
+ if (res > 0)
+ total += res;
+ } while ((res > 0 && total < len) || (res == -1 && errno == EINTR));
+ return total;
+}
+/*
* transport_connect:
*
* Connect/Listen on HOST:PORT. If HOST is NULL, generate an address and listen on it.
@@ -1029,11 +1047,13 @@ transport_connect (const char *host, int port)
/* Write handshake message */
sprintf (handshake_msg, "DWP-Handshake");
- res = send (conn_fd, handshake_msg, strlen (handshake_msg), 0);
+ do {
+ res = send (conn_fd, handshake_msg, strlen (handshake_msg), 0);
+ } while (res == -1 && errno == EINTR);
g_assert (res != -1);
/* Read answer */
- res = recv (conn_fd, buf, strlen (handshake_msg), 0);
+ res = recv_length (conn_fd, buf, strlen (handshake_msg), 0);
if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg) != 0))) {
fprintf (stderr, "debugger-agent: DWP handshake failed.\n");
exit (1);
@@ -1059,7 +1079,9 @@ transport_send (guint8 *data, int len)
{
int res;
- res = send (conn_fd, data, len, 0);
+ do {
+ res = send (conn_fd, data, len, 0);
+ } while (res == -1 && errno == EINTR);
if (res != len)
return FALSE;
else
@@ -5959,7 +5981,7 @@ debugger_thread (void *arg)
mono_set_is_debugger_attached (TRUE);
while (TRUE) {
- res = recv (conn_fd, header, HEADER_LENGTH, 0);
+ res = recv_length (conn_fd, header, HEADER_LENGTH, 0);
/* This will break if the socket is closed during shutdown too */
if (res != HEADER_LENGTH)
@@ -5981,7 +6003,7 @@ debugger_thread (void *arg)
data = g_malloc (len - HEADER_LENGTH);
if (len - HEADER_LENGTH > 0)
{
- res = recv (conn_fd, data, len - HEADER_LENGTH, 0);
+ res = recv_length (conn_fd, data, len - HEADER_LENGTH, 0);
if (res != len - HEADER_LENGTH)
break;
}
diff --git a/mono/mini/driver.c b/mono/mini/driver.c
index e9068d9278e..c4e7f4ccdb3 100644
--- a/mono/mini/driver.c
+++ b/mono/mini/driver.c
@@ -1333,7 +1333,7 @@ mono_main (int argc, char* argv[])
mini_verbose++;
} else if (strcmp (argv [i], "--version") == 0 || strcmp (argv [i], "-V") == 0) {
char *build = mono_get_runtime_build_info ();
- g_print ("Mono JIT compiler version %s\nCopyright (C) 2002-2008 Novell, Inc and Contributors. www.mono-project.com\n", build);
+ g_print ("Mono JIT compiler version %s\nCopyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com\n", build);
g_free (build);
g_print (info);
if (mini_verbose) {
diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c
index 4b79838bb30..d33d47db8cc 100644
--- a/mono/mini/mini-arm.c
+++ b/mono/mini/mini-arm.c
@@ -1113,6 +1113,32 @@ mono_arch_allocate_vars (MonoCompile *cfg)
cfg->sig_cookie += sizeof (gpointer);
}
+ /* Allocate these first so they have a small offset, OP_SEQ_POINT depends on this */
+ if (cfg->arch.seq_point_info_var) {
+ MonoInst *ins;
+
+ ins = cfg->arch.seq_point_info_var;
+
+ size = 4;
+ align = 4;
+ offset += align - 1;
+ offset &= ~(align - 1);
+ ins->opcode = OP_REGOFFSET;
+ ins->inst_basereg = frame_reg;
+ ins->inst_offset = offset;
+ offset += size;
+
+ ins = cfg->arch.ss_trigger_page_var;
+ size = 4;
+ align = 4;
+ offset += align - 1;
+ offset &= ~(align - 1);
+ ins->opcode = OP_REGOFFSET;
+ ins->inst_basereg = frame_reg;
+ ins->inst_offset = offset;
+ offset += size;
+ }
+
curinst = cfg->locals_start;
for (i = curinst; i < cfg->num_varinfo; ++i) {
inst = cfg->varinfo [i];
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index 8554f600c0b..69564bce4fd 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -4320,8 +4320,13 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
mono_raise_exception (exc);
}
- if (prof_options & MONO_PROFILE_JIT_COMPILATION)
- mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
+ if (prof_options & MONO_PROFILE_JIT_COMPILATION) {
+ if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
+ /* The profiler doesn't know about wrappers, so pass the original icall method */
+ mono_profiler_method_end_jit (mono_marshal_method_from_wrapper (method), jinfo, MONO_PROFILE_OK);
+ else
+ mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
+ }
mono_runtime_class_init (vtable);
return code;
@@ -4789,6 +4794,13 @@ SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler)
}
#endif
+#ifndef PLATFORM_WIN32
+ if (mono_aot_is_pagefault (info->si_addr)) {
+ mono_aot_handle_pagefault (info->si_addr);
+ return;
+ }
+#endif
+
/* The thread might no be registered with the runtime */
if (!mono_domain_get () || !jit_tls) {
if (mono_chain_signal (SIG_HANDLER_PARAMS))
@@ -5190,6 +5202,10 @@ mini_init (const char *filename, const char *runtime_version)
mono_install_get_class_from_name (mono_aot_get_class_from_name);
mono_install_jit_info_find_in_aot (mono_aot_find_jit_info);
+ if (debug_options.collect_pagefault_stats) {
+ mono_aot_set_make_unreadable (TRUE);
+ }
+
if (runtime_version)
domain = mono_init_version (filename, runtime_version);
else
diff --git a/mono/mini/mini.h b/mono/mini/mini.h
index b8aa756f8c4..3246002206e 100644
--- a/mono/mini/mini.h
+++ b/mono/mini/mini.h
@@ -1492,6 +1492,9 @@ char* mono_aot_wrapper_name (MonoMethod *method) MONO_INTERNAL;
MonoAotTrampInfo* mono_aot_tramp_info_create (const char *name, guint8 *code, guint32 code_len) MONO_INTERNAL;
guint mono_aot_str_hash (gconstpointer v1) MONO_INTERNAL;
MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INTERNAL;
+void mono_aot_set_make_unreadable (gboolean unreadable) MONO_INTERNAL;
+gboolean mono_aot_is_pagefault (void *ptr) MONO_INTERNAL;
+void mono_aot_handle_pagefault (void *ptr) MONO_INTERNAL;
/* This is an exported function */
void mono_aot_register_globals (gpointer *globals);
diff --git a/mono/profiler/ChangeLog b/mono/profiler/ChangeLog
index 25544b0f8a5..8ee5814f5ad 100644
--- a/mono/profiler/ChangeLog
+++ b/mono/profiler/ChangeLog
@@ -1,3 +1,9 @@
+2010-02-13 Zoltan Varga <vargaz@gmail.com>
+
+ * mono-profiler-aot.c (output_image): Emit method names instead of tokens so
+ the info can be used for different versions of the same assembly. Don't append
+ the assembly guid to the file names.
+
2010-01-11 Zoltan Varga <vargaz@gmail.com>
* mono-profiler-logging.c (_ProfilerFileWriteBuffer): Use MONO_ZERO_LEN_ARRAY.
diff --git a/mono/profiler/mono-profiler-aot.c b/mono/profiler/mono-profiler-aot.c
index 9b771525326..92285bbca99 100644
--- a/mono/profiler/mono-profiler-aot.c
+++ b/mono/profiler/mono-profiler-aot.c
@@ -41,11 +41,14 @@ foreach_method (gpointer data, gpointer user_data)
{
ForeachData *udata = (ForeachData*)user_data;
MonoMethod *method = (MonoMethod*)data;
+ char *name;
if (!mono_method_get_token (method) || mono_class_get_image (mono_method_get_class (method)) != udata->image)
return;
- fprintf (udata->outfile, "%d\n", mono_method_get_token (method));
+ name = mono_method_full_name (method, TRUE);
+ fprintf (udata->outfile, "%s\n", name);
+ g_free (name);
}
static void
@@ -75,7 +78,7 @@ output_image (gpointer key, gpointer value, gpointer user_data)
i = 0;
while (TRUE) {
- outfile_name = g_strdup_printf ("%s/%s-%s-%d", tmp, mono_image_get_name (image), mono_image_get_guid (image), i);
+ outfile_name = g_strdup_printf ("%s/%s-%d", tmp, mono_image_get_name (image), i);
if (!g_file_test (outfile_name, G_FILE_TEST_IS_REGULAR))
break;
@@ -88,7 +91,7 @@ output_image (gpointer key, gpointer value, gpointer user_data)
outfile = fopen (outfile_name, "w+");
g_assert (outfile);
- fprintf (outfile, "#VER:%d\n", 1);
+ fprintf (outfile, "#VER:%d\n", 2);
data.prof = prof;
data.outfile = outfile;