Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ecf447d
Initial metadata-update prototype
lambdageek Nov 2, 2020
631525a
Add metadata-update.{c,h} to CMakeLists.txt
lambdageek Nov 2, 2020
d1dc08c
fix icall-def-netcore typo
lambdageek Nov 2, 2020
8b9992f
Add icall to corelib
lambdageek Nov 2, 2020
971b970
Add console and browser metadata update samples
lambdageek Nov 2, 2020
3b93069
Add README for mbr samples
lambdageek Nov 18, 2020
f5b6a73
[build] Add initial runtime support for MonoMetadataUpdate property
lambdageek Nov 18, 2020
135efa5
[runtime] ifdef out metadata updates if not enabled
lambdageek Nov 6, 2020
486b572
[wasm] set log mask to metadata-update
lambdageek Dec 3, 2020
0e37891
[mbr] Add InjectUpdate fn to sample
lambdageek Dec 3, 2020
d76c153
[metadata-update] don't merge heaps
lambdageek Dec 3, 2020
0de44c5
Don't make entrypoint public yet
lambdageek Nov 6, 2020
05e8c36
Add LoadMetadataUpdate to linker descriptor
lambdageek Dec 6, 2020
91080db
[wasm] add default Makefile variable value
lambdageek Dec 6, 2020
2f69e35
fix mono/mono CI
lambdageek Dec 6, 2020
e847fd8
remove mono/mono/tests/enc
lambdageek Dec 7, 2020
122e8bd
[metadata-update] Add per-thread exposed generation
lambdageek Dec 9, 2020
d98a6fa
[mbr] Fixup console sample
lambdageek Dec 15, 2020
a2a252e
[metadata-update] delete unused method
lambdageek Dec 15, 2020
44e165f
[mbr] Use 2 threads in console sample
lambdageek Dec 15, 2020
687516f
[metadata-update] Respect exposed generation in MethdDef RVA lookups
lambdageek Dec 15, 2020
a7c10c2
[interp] Expose latest metadata update before transforming methods
lambdageek Dec 15, 2020
e629fb6
[mbr] Update samples after rebase
lambdageek Dec 16, 2020
a0ab40e
[metadata-update] Don't fail after the first unsupported edit
lambdageek Dec 16, 2020
a402aa1
[metadata_update] Keep track of logical table sizes for deltas
lambdageek Nov 2, 2020
6429372
[metadata-update] Use a GList for MonoImage:delta_image
lambdageek Dec 18, 2020
d3fc78e
[metadata-update] add effective table lookup debug output
lambdageek Dec 18, 2020
dce3d2c
Address review feedback
lambdageek Jan 7, 2021
945b060
[interp] Save top interp frame at MINT_SAFEPOINT to ThreadContext
lambdageek Jan 9, 2021
d40eb92
[mbr] Extend console sample
lambdageek Jan 9, 2021
04e153c
[interp] Check mono_polling_required at safepoint
lambdageek Jan 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/mono/mono/mini/interp/interp-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ typedef struct {
guchar *stack_pointer;
/* Used for allocation of localloc regions */
FrameDataAllocator data_stack;
/* Used when a thread self-suspends at a safepoint in the interpreter, points to the
* currently executing frame. (If a thread self-suspends somewhere else in the runtime, this
* is NULL - the LMF will point to the InterpFrame before the thread exited the interpreter)
*/
InterpFrame *safepoint_frame;
} ThreadContext;

typedef struct {
Expand Down
65 changes: 54 additions & 11 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ clear_resume_state (ThreadContext *context)
g_assert (context->exc_gchandle);
mono_gchandle_free_internal (context->exc_gchandle);
context->exc_gchandle = 0;
context->safepoint_frame = NULL;
Comment thread
lambdageek marked this conversation as resolved.
Outdated
}

/*
Expand Down Expand Up @@ -420,6 +421,8 @@ interp_free_context (gpointer ctx)
set_context (NULL);
}

context->safepoint_frame = NULL;

mono_vfree (context->stack_start, INTERP_STACK_SIZE, MONO_MEM_ACCOUNT_INTERP_STACK);
/* Prevent interp_mark_stack from trying to scan the data_stack, before freeing it */
context->stack_start = NULL;
Expand All @@ -428,6 +431,19 @@ interp_free_context (gpointer ctx)
g_free (context);
}

static void
context_set_safepoint_frame (ThreadContext *context, InterpFrame *frame)
{
g_assert (!context->has_resume_state);
context->safepoint_frame = frame;
}

static void
context_clear_safepoint_frame (ThreadContext *context)
{
context->safepoint_frame = NULL;
}

void
mono_interp_error_cleanup (MonoError* error)
{
Expand Down Expand Up @@ -2014,6 +2030,7 @@ interp_entry (InterpEntryData *data)
context->stack_pointer = (guchar*)sp;

g_assert (!context->has_resume_state);
g_assert (!context->safepoint_frame);

if (rmethod->needs_thread_attach)
mono_threads_detach_coop (orig_domain, &attach_cookie);
Expand Down Expand Up @@ -5218,9 +5235,11 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
MINT_IN_CASE(MINT_SAFEPOINT)
/* Do synchronous checking of abort requests */
EXCEPTION_CHECKPOINT;
context_set_safepoint_frame (context, frame);
Comment thread
lambdageek marked this conversation as resolved.
Outdated
/* Poll safepoint */
mono_threads_safepoint ();
++ip;
context_clear_safepoint_frame (context);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDFLDA_UNSAFE) {
sp[-1].data.p = (char*)sp [-1].data.o + ip [1];
Expand Down Expand Up @@ -7574,39 +7593,63 @@ interp_metadata_update_init (MonoError *error)
mono_error_set_execution_engine (error, "Interpreter inlining must be turned off for metadata updates");
}

#ifdef ENABLE_METADATA_UPDATE
static void
interp_invalidate_transformed (MonoDomain *domain)
metadata_update_backup_frames (MonoDomain *domain, MonoThreadInfo *info, InterpFrame *frame)
{
gboolean need_stw_restart = FALSE;
#ifdef ENABLE_METADATA_UPDATE
need_stw_restart = TRUE;
while (frame) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "threadinfo=%p, copy imethod for method=%s", info, mono_method_full_name (frame->imethod->method, 1));
copy_imethod_for_frame (domain, frame);
frame = frame->parent;
}
}

mono_gc_stop_world ();
static void
metadata_update_prepare_to_invalidate (MonoDomain *domain)
{
/* (1) make a copy of imethod for every interpframe that is on the stack,
* so we do not invalidate currently running methods */

FOREACH_THREAD_EXCLUDE (info, MONO_THREAD_INFO_FLAGS_NO_GC) {
if (!info)
if (!info || !info->jit_data)
continue;

ThreadContext *context = (ThreadContext*)info->jit_data->interp_context;

/* If the thread was in the interpreter and hit a safepoint
* opcode and suspended, backup the frames since the last lmf.
*/
if (context && context->safepoint_frame) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "threadinfo=%p, has safepoint frame %p", info, context->safepoint_frame);
metadata_update_backup_frames (domain, info, context->safepoint_frame);
}

MonoLMF *lmf = info->jit_data->lmf;
Comment thread
lambdageek marked this conversation as resolved.
Outdated
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, "threadinfo=%p, copy imethod for method=%s", info, mono_method_full_name (frame->imethod->method, 1));
copy_imethod_for_frame (domain, frame);
frame = frame->parent;
}
metadata_update_backup_frames (domain, info, frame);
}
}
lmf = (MonoLMF *)(((gsize) lmf->previous_lmf) & ~3);
}
} FOREACH_THREAD_END

/* (2) invalidate all the registered imethods */
}
#endif


static void
interp_invalidate_transformed (MonoDomain *domain)
{
gboolean need_stw_restart = FALSE;
#ifdef ENABLE_METADATA_UPDATE
need_stw_restart = TRUE;
mono_gc_stop_world ();
metadata_update_prepare_to_invalidate (domain);
#endif
MonoJitDomainInfo *info = domain_jit_info (domain);
mono_domain_jit_code_hash_lock (domain);
Expand Down