-/*
- * jit-info.c: MonoJitInfo functionality
+/**
+ * \file
+ * MonoJitInfo functionality
*
* Author:
* Dietmar Maurer (dietmar@ximian.com)
#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>
#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>
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*
table->domain = domain;
table->num_chunks = 1;
table->chunks [0] = jit_info_table_new_chunk ();
+ table->num_valid = 0;
return table;
}
while (left < right) {
int pos = (left + right) / 2;
- MonoJitInfo *ji = (MonoJitInfo *)get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
+ MonoJitInfo *ji = (MonoJitInfo *)mono_get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
gint8 *code_end = (gint8*)ji->code_start + ji->code_size;
if (addr < code_end)
MonoJitInfoTableChunk *chunk = table->chunks [chunk_pos];
while (pos < chunk->num_elements) {
- ji = (MonoJitInfo *)get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
+ ji = (MonoJitInfo *)mono_get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
++pos;
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
table by a hazard pointer and make sure that the pointer is
still there after we've made it hazardous, we don't have to
worry about the writer freeing the table. */
- table = (MonoJitInfoTable *)get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX);
+ table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX);
ji = jit_info_table_find (table, hp, (gint8*)addr);
if (hp)
/* Maybe its an AOT module */
if (try_aot && mono_get_root_domain () && mono_get_root_domain ()->aot_modules) {
- table = (MonoJitInfoTable *)get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX);
+ table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX);
module_ji = jit_info_table_find (table, hp, (gint8*)addr);
if (module_ji)
ji = jit_info_find_in_aot_func (domain, module_ji->d.image, addr);
/**
* 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)
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 ();
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) {
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) {
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);
}
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);
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);
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);
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;
}
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)
/**
* 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)
/**
* 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)
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;
+ }
+}