Skip to content

Commit b9afea1

Browse files
richard-finejoncham
authored andcommitted
Extend mono_profile with more functions to work with coverage data
1 parent 14c1736 commit b9afea1

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

mono/metadata/profiler.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,115 @@ mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method,
407407

408408
return TRUE;
409409
}
410+
411+
static void invoke_coverage_callback_for_hashtable_entry (gpointer key, gpointer value, gpointer user_data)
412+
{
413+
MonoMethod* method = (MonoMethod*)key;
414+
MonoProfilerCoverageInfo *info = (MonoProfilerCoverageInfo*)value;
415+
MonoProfilerCoverageCallback cb = (MonoProfilerCoverageCallback)user_data;
416+
417+
MonoError error;
418+
MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
419+
mono_error_assert_ok (&error);
420+
421+
guint32 size;
422+
423+
const unsigned char *start = mono_method_header_get_code (header, &size, NULL);
424+
const unsigned char *end = start + size;
425+
MonoDebugMethodInfo *minfo = mono_debug_lookup_method (method);
426+
427+
for (guint32 i = 0; i < info->entries; i++) {
428+
guchar *cil_code = info->data [i].cil_code;
429+
430+
if (cil_code && cil_code >= start && cil_code < end) {
431+
guint32 offset = cil_code - start;
432+
433+
MonoProfilerCoverageData data = {
434+
.method = method,
435+
.il_offset = offset,
436+
.counter = info->data [i].count,
437+
.line = 1,
438+
.column = 1,
439+
};
440+
441+
if (minfo) {
442+
MonoDebugSourceLocation *loc = mono_debug_method_lookup_location (minfo, offset);
443+
444+
if (loc) {
445+
data.file_name = g_strdup (loc->source_file);
446+
data.line = loc->row;
447+
data.column = loc->column;
448+
449+
mono_debug_free_source_location (loc);
450+
}
451+
}
452+
453+
cb (handle->prof, &data);
454+
455+
g_free ((char *) data.file_name);
456+
}
457+
}
458+
459+
mono_metadata_free_mh (header);
460+
}
461+
462+
mono_bool
463+
mono_profiler_get_all_coverage_data(MonoProfilerHandle handle, MonoProfilerCoverageCallback cb)
464+
{
465+
if (!mono_profiler_state.code_coverage)
466+
return FALSE;
467+
468+
coverage_lock ();
469+
470+
g_hash_table_foreach (mono_profiler_state.coverage_hash, invoke_coverage_callback_for_hashtable_entry, cb);
471+
472+
coverage_unlock ();
473+
474+
return TRUE;
475+
}
476+
477+
void
478+
mono_profiler_reset_coverage(MonoMethod* method)
479+
{
480+
if (!mono_profiler_state.code_coverage)
481+
return;
482+
483+
if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
484+
return;
485+
486+
coverage_lock ();
487+
488+
MonoProfilerCoverageInfo *info = g_hash_table_lookup (mono_profiler_state.coverage_hash, method);
489+
490+
coverage_unlock ();
491+
492+
if (!info)
493+
return;
494+
495+
for (guint32 i = 0; i < info->entries; i++)
496+
info->data[i].count = 0;
497+
}
498+
499+
static void reset_coverage_for_hashtable_entry (gpointer key, gpointer value, gpointer user_data)
500+
{
501+
MonoProfilerCoverageInfo *info = (MonoProfilerCoverageInfo*)value;
502+
503+
for (guint32 i = 0; i < info->entries; i++)
504+
info->data[i].count = 0;
505+
}
506+
507+
void mono_profiler_reset_all_coverage()
508+
{
509+
if (!mono_profiler_state.code_coverage)
510+
return;
511+
512+
coverage_lock ();
513+
514+
g_hash_table_foreach (mono_profiler_state.coverage_hash, reset_coverage_for_hashtable_entry, NULL);
515+
516+
coverage_unlock ();
517+
}
518+
410519
#endif
411520

412521
MonoProfilerCoverageInfo *

mono/metadata/profiler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ MONO_API mono_bool mono_profiler_enable_coverage (void);
4545
MONO_API void mono_profiler_set_coverage_filter_callback (MonoProfilerHandle handle, MonoProfilerCoverageFilterCallback cb);
4646
#ifndef RUNTIME_IL2CPP
4747
MONO_API mono_bool mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method, MonoProfilerCoverageCallback cb);
48+
MONO_API mono_bool mono_profiler_get_all_coverage_data(MonoProfilerHandle handle, MonoProfilerCoverageCallback cb);
49+
50+
MONO_API mono_bool mono_profiler_reset_coverage(MonoMethod* method);
51+
MONO_API void mono_profiler_reset_all_coverage();
4852
#endif
4953

5054
typedef enum {

0 commit comments

Comments
 (0)