Beispiel #1
0
MonoProfileCoverageInfo* 
mono_profiler_coverage_alloc (MonoMethod *method, int entries)
{
	MonoProfileCoverageInfo *res;
	int instrument = FALSE;
	ProfilerDesc *prof;

	for (prof = prof_list; prof; prof = prof->next) {
		/* note that we call the filter on all the profilers even if just
		 * a single one would be enough to instrument a method
		 */
		if (prof->coverage_filter_cb)
			if (prof->coverage_filter_cb (prof->profiler, method))
				instrument = TRUE;
	}
	if (!instrument)
		return NULL;

	mono_profiler_coverage_lock ();
	if (!coverage_hash)
		coverage_hash = g_hash_table_new (NULL, NULL);

	res = g_malloc0 (sizeof (MonoProfileCoverageInfo) + sizeof (void*) * 2 * entries);

	res->entries = entries;

	g_hash_table_insert (coverage_hash, method, res);
	mono_profiler_coverage_unlock ();

	return res;
}
Beispiel #2
0
/* safe only when the method antive code has been unloaded */
void
mono_profiler_coverage_free (MonoMethod *method)
{
	MonoProfileCoverageInfo* info;

	mono_profiler_coverage_lock ();
	if (!coverage_hash) {
		mono_profiler_coverage_unlock ();
		return;
	}

	info = g_hash_table_lookup (coverage_hash, method);
	if (info) {
		g_free (info);
		g_hash_table_remove (coverage_hash, method);
	}
	mono_profiler_coverage_unlock ();
}
Beispiel #3
0
/**
 * mono_profiler_coverage_get:
 * @prof: The profiler handle, installed with mono_profiler_install
 * @method: the method to gather information from.
 * @func: A routine that will be called back with the results
 *
 * If the MONO_PROFILER_INS_COVERAGE flag was active during JIT compilation
 * it is posisble to obtain coverage information about a give method.
 *
 * The function @func will be invoked repeatedly with instances of the
 * MonoProfileCoverageEntry structure.
 */
void 
mono_profiler_coverage_get (MonoProfiler *prof, MonoMethod *method, MonoProfileCoverageFunc func)
{
	MonoError error;
	MonoProfileCoverageInfo* info = NULL;
	int i, offset;
	guint32 code_size;
	const unsigned char *start, *end, *cil_code;
	MonoMethodHeader *header;
	MonoProfileCoverageEntry entry;
	MonoDebugMethodInfo *debug_minfo;

	mono_profiler_coverage_lock ();
	if (coverage_hash)
		info = (MonoProfileCoverageInfo *)g_hash_table_lookup (coverage_hash, method);
	mono_profiler_coverage_unlock ();

	if (!info)
		return;

	header = mono_method_get_header_checked (method, &error);
	mono_error_assert_ok (&error);
	start = mono_method_header_get_code (header, &code_size, NULL);
	debug_minfo = mono_debug_lookup_method (method);

	end = start + code_size;
	for (i = 0; i < info->entries; ++i) {
		cil_code = info->data [i].cil_code;
		if (cil_code && cil_code >= start && cil_code < end) {
			char *fname = NULL;
			offset = cil_code - start;
			entry.iloffset = offset;
			entry.method = method;
			entry.counter = info->data [i].count;
			entry.line = entry.col = 1;
			entry.filename = NULL;
			if (debug_minfo) {
				MonoDebugSourceLocation *location;

				location = mono_debug_symfile_lookup_location (debug_minfo, offset);
				if (location) {
					entry.line = location->row;
					entry.col = location->column;
					entry.filename = fname = g_strdup (location->source_file);
					mono_debug_free_source_location (location);
				}
			}

			func (prof, &entry);
			g_free (fname);
		}
	}
	mono_metadata_free_mh (header);
}