Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / metadata / jit-info.c
index 6ffff1a6b7328511743975d2b247935fe7aa9d6d..3344679e81236c9bdd9138a45f00d58d7986ad26 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * jit-info.c: MonoJitInfo functionality
+/**
+ * \file
+ * MonoJitInfo functionality
  *
  * Author:
  *     Dietmar Maurer (dietmar@ximian.com)
@@ -27,6 +28,7 @@
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/unlocked.h>
 #include <mono/metadata/object.h>
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/domain-internals.h>
@@ -34,9 +36,8 @@
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/metadata-internals.h>
-#include <mono/metadata/gc-internals.h>
 #include <mono/metadata/appdomain.h>
-#include <mono/metadata/mono-debug-debugger.h>
+#include <mono/metadata/debug-internals.h>
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/runtime.h>
@@ -62,21 +63,7 @@ static MonoJitInfoFindInAot jit_info_find_in_aot_func = NULL;
 static int
 jit_info_table_num_elements (MonoJitInfoTable *table)
 {
-       int i;
-       int num_elements = 0;
-
-       for (i = 0; i < table->num_chunks; ++i) {
-               MonoJitInfoTableChunk *chunk = table->chunks [i];
-               int chunk_num_elements = chunk->num_elements;
-               int j;
-
-               for (j = 0; j < chunk_num_elements; ++j) {
-                       if (!IS_JIT_INFO_TOMBSTONE (chunk->data [j]))
-                               ++num_elements;
-               }
-       }
-
-       return num_elements;
+       return table->num_valid;
 }
 
 static MonoJitInfoTableChunk*
@@ -96,6 +83,7 @@ mono_jit_info_table_new (MonoDomain *domain)
        table->domain = domain;
        table->num_chunks = 1;
        table->chunks [0] = jit_info_table_new_chunk ();
+       table->num_valid = 0;
 
        return table;
 }
@@ -276,7 +264,7 @@ mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_
        MonoJitInfo *ji, *module_ji;
        MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
 
-       ++mono_stats.jit_info_table_lookup_count;
+       UnlockedIncrement (&mono_stats.jit_info_table_lookup_count);
 
        /* First we have to get the domain's jit_info_table.  This is
           complicated by the fact that a writer might substitute a
@@ -314,18 +302,18 @@ mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_
 
 /**
  * mono_jit_info_table_find:
- * @domain: Domain that you want to look up
- * @addr: Points to an address with JITed code.
+ * \param domain Domain that you want to look up
+ * \param addr Points to an address with JITed code.
  *
- * Use this function to obtain a `MonoJitInfo*` object that can be used to get
- * some statistics.   You should provide both the @domain on which you will be
- * performing the probe, and an address.   Since application domains can share code
+ * Use this function to obtain a \c MonoJitInfo* object that can be used to get
+ * some statistics. You should provide both the \p domain on which you will be
+ * performing the probe, and an address. Since application domains can share code
  * the same address can be in use by multiple domains at once.
  *
  * This does not return any results for trampolines.
  *
- * Returns: NULL if the address does not belong to JITed code (it might be native
- * code or a trampoline) or a valid pointer to a `MonoJitInfo*`.
+ * \returns NULL if the address does not belong to JITed code (it might be native
+ * code or a trampoline) or a valid pointer to a \c MonoJitInfo* .
  */
 MonoJitInfo*
 mono_jit_info_table_find (MonoDomain *domain, char *addr)
@@ -397,6 +385,7 @@ jit_info_table_realloc (MonoJitInfoTable *old)
        result = (MonoJitInfoTable *)g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*) * num_chunks);
        result->domain = old->domain;
        result->num_chunks = num_chunks;
+       result->num_valid = old->num_valid;
 
        for (i = 0; i < num_chunks; ++i)
                result->chunks [i] = jit_info_table_new_chunk ();
@@ -469,6 +458,7 @@ jit_info_table_copy_and_split_chunk (MonoJitInfoTable *table, MonoJitInfoTableCh
 
        new_table->domain = table->domain;
        new_table->num_chunks = table->num_chunks + 1;
+       new_table->num_valid = table->num_valid;
 
        j = 0;
        for (i = 0; i < table->num_chunks; ++i) {
@@ -517,6 +507,7 @@ jit_info_table_copy_and_purify_chunk (MonoJitInfoTable *table, MonoJitInfoTableC
 
        new_table->domain = table->domain;
        new_table->num_chunks = table->num_chunks;
+       new_table->num_valid = table->num_valid;
 
        j = 0;
        for (i = 0; i < table->num_chunks; ++i) {
@@ -651,6 +642,8 @@ jit_info_table_add (MonoDomain *domain, MonoJitInfoTable *volatile *table_ptr, M
        chunk->last_code_end = (gint8*)chunk->data [chunk->num_elements - 1]->code_start
                + chunk->data [chunk->num_elements - 1]->code_size;
 
+       ++table->num_valid;
+
        /* Debugging code, should be removed. */
        //jit_info_table_check (table);
 }
@@ -662,7 +655,7 @@ mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji)
 
        mono_domain_lock (domain);
 
-       ++mono_stats.jit_info_table_insert_count;
+       UnlockedIncrement (&mono_stats.jit_info_table_insert_count);
 
        jit_info_table_add (domain, &domain->jit_info_table, ji);
 
@@ -732,6 +725,7 @@ jit_info_table_remove (MonoJitInfoTable *table, MonoJitInfo *ji)
        g_assert (chunk->data [pos] == ji);
 
        chunk->data [pos] = mono_jit_info_make_tombstone (chunk, ji);
+       --table->num_valid;
 
        /* Debugging code, should be removed. */
        //jit_info_table_check (table);
@@ -745,7 +739,7 @@ mono_jit_info_table_remove (MonoDomain *domain, MonoJitInfo *ji)
        mono_domain_lock (domain);
        table = domain->jit_info_table;
 
-       ++mono_stats.jit_info_table_remove_count;
+       UnlockedIncrement (&mono_stats.jit_info_table_remove_count);
 
        jit_info_table_remove (table, ji);
 
@@ -801,6 +795,8 @@ mono_jit_info_size (MonoJitInfoFlags flags, int num_clauses, int num_holes)
                size += sizeof (MonoArchEHJitInfo);
        if (flags & JIT_INFO_HAS_THUNK_INFO)
                size += sizeof (MonoThunkJitInfo);
+       if (flags & JIT_INFO_HAS_UNWIND_INFO)
+               size += sizeof (MonoUnwindJitInfo);
        return size;
 }
 
@@ -820,17 +816,19 @@ mono_jit_info_init (MonoJitInfo *ji, MonoMethod *method, guint8 *code, int code_
                ji->has_arch_eh_info = 1;
        if (flags & JIT_INFO_HAS_THUNK_INFO)
                ji->has_thunk_info = 1;
+       if (flags & JIT_INFO_HAS_UNWIND_INFO)
+               ji->has_unwind_info = 1;
 }
 
 /**
  * mono_jit_info_get_code_start:
- * @ji: the JIT information handle
+ * \param ji the JIT information handle
  *
  * Use this function to get the starting address for the method described by
- * the @ji object.  You can use this plus the `mono_jit_info_get_code_size`
+ * the \p ji object.  You can use this plus the \c mono_jit_info_get_code_size
  * to determine the start and end of the native code.
  *
- * Returns: Starting address with the native code.
+ * \returns Starting address with the native code.
  */
 gpointer
 mono_jit_info_get_code_start (MonoJitInfo* ji)
@@ -840,13 +838,13 @@ mono_jit_info_get_code_start (MonoJitInfo* ji)
 
 /**
  * mono_jit_info_get_code_size:
- * @ji: the JIT information handle
+ * \param ji the JIT information handle
  *
  * Use this function to get the code size for the method described by
- * the @ji object.   You can use this plus the `mono_jit_info_get_code_start`
+ * the \p ji object. You can use this plus the \c mono_jit_info_get_code_start
  * to determine the start and end of the native code.
  *
- * Returns: Starting address with the native code.
+ * \returns Starting address with the native code.
  */
 int
 mono_jit_info_get_code_size (MonoJitInfo* ji)
@@ -856,13 +854,13 @@ mono_jit_info_get_code_size (MonoJitInfo* ji)
 
 /**
  * mono_jit_info_get_method:
- * @ji: the JIT information handle
+ * \param ji the JIT information handle
  *
- * Use this function to get the `MonoMethod *` that backs
- * the @ji object.
+ * Use this function to get the \c MonoMethod* that backs
+ * the \p ji object.
  *
- * Returns: The MonoMethod that represents the code tracked
- * by @ji.
+ * \returns The \c MonoMethod that represents the code tracked
+ * by \p ji.
  */
 MonoMethod*
 mono_jit_info_get_method (MonoJitInfo* ji)
@@ -996,3 +994,22 @@ mono_jit_info_get_thunk_info (MonoJitInfo *ji)
                return NULL;
        }
 }
+
+MonoUnwindJitInfo*
+mono_jit_info_get_unwind_info (MonoJitInfo *ji)
+{
+       if (ji->has_unwind_info) {
+               char *ptr = (char*)&ji->clauses [ji->num_clauses];
+               if (ji->has_generic_jit_info)
+                       ptr += sizeof (MonoGenericJitInfo);
+               if (ji->has_try_block_holes)
+                       ptr += try_block_hole_table_size (ji);
+               if (ji->has_arch_eh_info)
+                       ptr += sizeof (MonoArchEHJitInfo);
+               if (ji->has_thunk_info)
+                       ptr += sizeof (MonoThunkJitInfo);
+               return (MonoUnwindJitInfo*)ptr;
+       } else {
+               return NULL;
+       }
+}