Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Urban-Forster <lewurm@gmail.com>2020-04-29 11:58:13 +0300
committerBernhard Urban-Forster <lewurm@gmail.com>2020-04-29 11:58:13 +0300
commit751198342611a4c5273096bd474be2b272f0e19a (patch)
treea49b5cbaef2169918ed6e58c58381b13a07016c7
parent5fed14e09b3064c102ab80d19c148a08e522ff57 (diff)
[interp] make a copy of imethod if there is an active frame for it
So we do not modify it potentially during execution if another thread does the re-transformation.
-rw-r--r--mono/mini/interp/interp.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c
index 06ee213f60b..137cf5f6939 100644
--- a/mono/mini/interp/interp.c
+++ b/mono/mini/interp/interp.c
@@ -25,6 +25,7 @@
#include <mono/utils/gc_wrapper.h>
#include <mono/utils/mono-math.h>
#include <mono/utils/mono-counters.h>
+#include <mono/utils/mono-logger-internals.h>
#include <mono/utils/mono-tls-inline.h>
#include <mono/utils/mono-membar.h>
@@ -7587,8 +7588,41 @@ invalidate_transform (gpointer imethod_)
}
static void
+copy_imethod_for_frame (InterpFrame *frame)
+{
+ InterpMethod *copy = g_malloc0 (sizeof (InterpMethod));
+ memcpy (copy, frame->imethod, sizeof (InterpMethod));
+ copy->next_jit_code_hash = NULL; /* we don't want that in our copy */
+ frame->imethod = copy;
+ /* Note, the copy will leak eventually. If needed, we can add a bit upon
+ * frame cleanup. For now it should be good. */
+}
+
+static void
interp_invalidate_transformed (MonoDomain *domain)
{
+ /* TODO more locking */
+ /* (1) make a copy of imethod for every interpframe that is on the stack,
+ * so we do not invalidate currently running methods */
+
+ /* TODO: make it for each thread */
+ MonoLMF *lmf = mono_get_lmf ();
+ while (lmf) {
+ if (((gsize) lmf->previous_lmf) & 2) {
+ MonoLMFExt *ext = (MonoLMFExt *) lmf;
+ if (ext->kind == MONO_LMFEXT_INTERP_EXIT || ext->kind == MONO_LMFEXT_INTERP_EXIT_WITH_CTX) {
+ InterpFrame *frame = ext->interp_exit_data;
+ while (frame) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "copy imethod for method=%s\n", mono_method_full_name (frame->imethod->method, 1));
+ copy_imethod_for_frame (frame);
+ frame = frame->parent;
+ }
+ }
+ }
+ lmf = (MonoLMF *)(((gsize) lmf->previous_lmf) & ~3);
+ }
+
+ /* (2) invalidate all the registered imethods */
MonoJitDomainInfo *info = domain_jit_info (domain);
mono_domain_jit_code_hash_lock (domain);
mono_internal_hash_table_apply (&info->interp_code_hash, invalidate_transform);