Skip to content

Commit

Permalink
[Mono] Include loaded interpreter methods as EventPipe session rundow…
Browse files Browse the repository at this point in the history
…n method events. (dotnet#54953)

* Include interpreter methods in EventPipe session rundown events.

* Fix build error.
  • Loading branch information
lateralusX authored Jul 1, 2021
1 parent ca00588 commit 8dad364
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 19 deletions.
38 changes: 28 additions & 10 deletions src/mono/mono/eventpipe/ep-rt-mono.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ typedef struct _EventPipeSampleProfileData {
uintptr_t thread_ip;
uint32_t payload_data;
bool async_frame;
bool safe_point_frame;
} EventPipeSampleProfileData;

// Rundown flags.
Expand Down Expand Up @@ -898,13 +899,15 @@ eventpipe_execute_rundown (
if (root_domain) {
uint64_t domain_id = (uint64_t)root_domain;

// Iterate all functions in use (both JIT and AOT).
// Iterate all functions in use (JIT, AOT and Interpreter).
EventPipeFireMethodEventsData events_data;
events_data.domain = root_domain;
events_data.buffer_size = 1024 * sizeof(uint32_t);
events_data.buffer = g_new (uint8_t, events_data.buffer_size);
events_data.method_events_func = method_events_func;
mono_jit_info_table_foreach_internal (eventpipe_fire_method_events_func, &events_data);
if (mono_get_runtime_callbacks ()->is_interpreter_enabled())
mono_get_runtime_callbacks ()->interp_jit_info_foreach (eventpipe_fire_method_events_func, &events_data);
g_free (events_data.buffer);

// Iterate all assemblies in domain.
Expand Down Expand Up @@ -997,21 +1000,32 @@ eventpipe_sample_profiler_walk_managed_stack_for_thread_func (
EP_ASSERT (frame != NULL);
EP_ASSERT (data != NULL);

gboolean result = false;
EventPipeSampleProfileData *sample_data = (EventPipeSampleProfileData *)data;

if (sample_data->payload_data == EP_SAMPLE_PROFILER_SAMPLE_TYPE_ERROR) {
if (frame->type == FRAME_TYPE_MANAGED_TO_NATIVE)
switch (frame->type) {
case FRAME_TYPE_MANAGED:
sample_data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED;
break;
case FRAME_TYPE_MANAGED_TO_NATIVE:
case FRAME_TYPE_TRAMPOLINE:
sample_data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_EXTERNAL;
else
break;
case FRAME_TYPE_INTERP:
if (frame->managed)
sample_data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED;
else
sample_data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_EXTERNAL;
break;
case FRAME_TYPE_INTERP_TO_MANAGED:
case FRAME_TYPE_INTERP_TO_MANAGED_WITH_CTX:
break;
default:
sample_data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED;
}
}

bool safe_point_frame = false;
result = eventpipe_walk_managed_stack_for_thread (frame, ctx, &sample_data->stack_contents, &sample_data->async_frame, &safe_point_frame);
if (sample_data->payload_data == EP_SAMPLE_PROFILER_SAMPLE_TYPE_EXTERNAL && safe_point_frame)
sample_data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED;
return result;
return eventpipe_walk_managed_stack_for_thread (frame, ctx, &sample_data->stack_contents, &sample_data->async_frame, &sample_data->safe_point_frame);
}

static
Expand Down Expand Up @@ -1515,8 +1529,12 @@ ep_rt_mono_sample_profiler_write_sampling_event_for_threads (
data->thread_ip = (uintptr_t)MONO_CONTEXT_GET_IP (&thread_state->ctx);
data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_ERROR;
data->async_frame = FALSE;
data->safe_point_frame = FALSE;
ep_stack_contents_reset (&data->stack_contents);
mono_get_eh_callbacks ()->mono_walk_stack_with_state (eventpipe_sample_profiler_walk_managed_stack_for_thread_func, thread_state, MONO_UNWIND_SIGNAL_SAFE, data);
mono_get_eh_callbacks ()->mono_walk_stack_with_state (eventpipe_sample_profiler_walk_managed_stack_for_thread_func, thread_state, MONO_UNWIND_SIGNAL_SAFE, data);
if (data->payload_data == EP_SAMPLE_PROFILER_SAMPLE_TYPE_EXTERNAL && data->safe_point_frame)
data->payload_data = EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED;

sampled_thread_count++;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/mono/mono/metadata/object-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,9 @@ typedef struct {
/* Safely access System.Delegate from native code */
TYPED_HANDLE_DECL (MonoDelegate);


typedef void (*InterpJitInfoFunc) (MonoJitInfo *ji, gpointer user_data);

/*
* Callbacks supplied by the runtime and called by the modules in metadata/
* This interface is easier to extend than adding a new function type +
Expand Down Expand Up @@ -643,6 +646,7 @@ typedef struct {
void (*get_exception_stats)(guint32 *exception_count);
// Same as compile_method, but returns a MonoFtnDesc in llvmonly mode
gpointer (*get_ftnptr)(MonoMethod *method, MonoError *error);
void (*interp_jit_info_foreach)(InterpJitInfoFunc func, gpointer user_data);
} MonoRuntimeCallbacks;

typedef gboolean (*MonoInternalStackWalk) (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data);
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/ee.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ typedef gpointer MonoInterpFrameHandle;
MONO_EE_CALLBACK (void, invalidate_transformed, (void)) \
MONO_EE_CALLBACK (void, cleanup, (void)) \
MONO_EE_CALLBACK (void, mark_stack, (gpointer thread_info, GcScanFunc func, gpointer gc_data, gboolean precise)) \
MONO_EE_CALLBACK (void, jit_info_foreach, (InterpJitInfoFunc func, gpointer user_data)) \

typedef struct _MonoEECallbacks {

Expand Down
5 changes: 5 additions & 0 deletions src/mono/mono/mini/interp-stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ stub_mark_stack (gpointer thread_data, GcScanFunc func, gpointer gc_data, gboole
{
}

static void
stub_jit_info_foreach (InterpJitInfoFunc func, gpointer user_data)
{
}

#undef MONO_EE_CALLBACK
#define MONO_EE_CALLBACK(ret, name, sig) stub_ ## name,

Expand Down
33 changes: 29 additions & 4 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7325,7 +7325,7 @@ static int num_methods;
const int opcount_threshold = 100000;

static void
interp_add_imethod (gpointer method)
interp_add_imethod (gpointer method, gpointer user_data)
{
InterpMethod *imethod = (InterpMethod*) method;
if (imethod->opcounts > opcount_threshold)
Expand All @@ -7351,7 +7351,7 @@ interp_print_method_counts (void)

jit_mm_lock (jit_mm);
imethods = (InterpMethod**) malloc (jit_mm->interp_code_hash.num_entries * sizeof (InterpMethod*));
mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_add_imethod);
mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_add_imethod, NULL);
jit_mm_unlock (jit_mm);

qsort (imethods, num_methods, sizeof (InterpMethod*), imethod_opcount_comparer);
Expand All @@ -7372,7 +7372,7 @@ interp_set_optimizations (guint32 opts)
}

static void
invalidate_transform (gpointer imethod_)
invalidate_transform (gpointer imethod_, gpointer user_data)
{
InterpMethod *imethod = (InterpMethod *) imethod_;
imethod->transformed = FALSE;
Expand Down Expand Up @@ -7451,13 +7451,38 @@ interp_invalidate_transformed (void)
MonoJitMemoryManager *jit_mm = get_default_jit_mm ();

jit_mm_lock (jit_mm);
mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform);
mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL);
jit_mm_unlock (jit_mm);

if (need_stw_restart)
mono_restart_world (MONO_THREAD_INFO_FLAGS_NO_GC);
}

typedef struct {
InterpJitInfoFunc func;
gpointer user_data;
} InterpJitInfoFuncUserData;

static void
interp_call_jit_info_func (gpointer imethod, gpointer user_data)
{
InterpJitInfoFuncUserData *data = (InterpJitInfoFuncUserData *)user_data;
data->func (((InterpMethod *)imethod)->jinfo, data->user_data);
}

static void
interp_jit_info_foreach (InterpJitInfoFunc func, gpointer user_data)
{
InterpJitInfoFuncUserData data = {func, user_data};

// FIXME: Enumerate all memory managers
MonoJitMemoryManager *jit_mm = get_default_jit_mm ();

jit_mm_lock (jit_mm);
mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_call_jit_info_func, &data);
jit_mm_unlock (jit_mm);
}

static void
interp_cleanup (void)
{
Expand Down
9 changes: 8 additions & 1 deletion src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ GSList *mono_interp_only_classes;
static void register_icalls (void);
static void runtime_cleanup (MonoDomain *domain, gpointer user_data);
static void mini_invalidate_transformed_interp_methods (MonoAssemblyLoadContext *alc, uint32_t generation);
static void mini_interp_jit_info_foreach(InterpJitInfoFunc func, gpointer user_data);

gboolean
mono_running_on_valgrind (void)
Expand Down Expand Up @@ -4357,6 +4358,7 @@ mini_init (const char *filename, const char *runtime_version)
callbacks.install_state_summarizer = mini_register_sigterm_handler;
#endif
callbacks.metadata_update_published = mini_invalidate_transformed_interp_methods;
callbacks.interp_jit_info_foreach = mini_interp_jit_info_foreach;
callbacks.init_mem_manager = init_jit_mem_manager;
callbacks.free_mem_manager = free_jit_mem_manager;

Expand Down Expand Up @@ -5139,12 +5141,17 @@ mono_runtime_install_custom_handlers_usage (void)
}
#endif /* HOST_WIN32 */

void
static void
mini_invalidate_transformed_interp_methods (MonoAssemblyLoadContext *alc G_GNUC_UNUSED, uint32_t generation G_GNUC_UNUSED)
{
mini_get_interp_callbacks ()->invalidate_transformed ();
}

static void
mini_interp_jit_info_foreach(InterpJitInfoFunc func, gpointer user_data)
{
mini_get_interp_callbacks ()->jit_info_foreach (func, user_data);
}

/*
* mini_get_default_mem_manager:
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/utils/mono-internal-hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ mono_internal_hash_table_insert (MonoInternalHashTable *table,
}

void
mono_internal_hash_table_apply (MonoInternalHashTable *table, MonoInternalHashApplyFunc func)
mono_internal_hash_table_apply (MonoInternalHashTable *table, MonoInternalHashApplyFunc func, gpointer user_data)
{
for (gint i = 0; i < table->size; i++) {
gpointer head = table->table [i];
while (head) {
func (head);
func (head, user_data);
head = *(table->next_value (head));
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/utils/mono-internal-hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct _MonoInternalHashTable MonoInternalHashTable;

typedef gpointer (*MonoInternalHashKeyExtractFunc) (gpointer value);
typedef gpointer* (*MonoInternalHashNextValueFunc) (gpointer value);
typedef void (*MonoInternalHashApplyFunc) (gpointer value);
typedef void (*MonoInternalHashApplyFunc) (gpointer value, gpointer user_data);

struct _MonoInternalHashTable
{
Expand Down Expand Up @@ -73,7 +73,7 @@ mono_internal_hash_table_insert (MonoInternalHashTable *table,
gpointer key, gpointer value);

void
mono_internal_hash_table_apply (MonoInternalHashTable *table, MonoInternalHashApplyFunc func);
mono_internal_hash_table_apply (MonoInternalHashTable *table, MonoInternalHashApplyFunc func, gpointer user_data);

gboolean
mono_internal_hash_table_remove (MonoInternalHashTable *table, gpointer key);
Expand Down

0 comments on commit 8dad364

Please sign in to comment.