Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[interp] always require GC Unsafe mode in exception checkpoint #17016

Merged
merged 1 commit into from
Sep 26, 2019

Conversation

lewurm
Copy link
Contributor

@lewurm lewurm commented Sep 24, 2019

Follow-up for #16955

/cc @BrzVlad

@lewurm lewurm requested a review from BrzVlad September 24, 2019 11:11
@BrzVlad
Copy link
Member

BrzVlad commented Sep 24, 2019

Overall the code is a little fishy when it comes to this unsafe checking. Normally the wrapper does all the necessary transitions and we would know when to check and when not to check for exception inside the wrapper (I think this is how it works on jit). In the interpreter, I think we use this opcode for multiple scenarios, some of which require exception checking, some of which must not (and therefore the bug from the other PR).

Regardless, we should probably have a separate define, that does the state check, only for these icall opcodes. The check is redundant for other uses of EXCEPTION_CHECKPOINT (since we are by definition in unsafe state) and it might also confuse readers of code.

@lewurm
Copy link
Contributor Author

lewurm commented Sep 25, 2019

You are right, the wrapper could do it:

mono/mono/metadata/marshal.c

Lines 3447 to 3449 in aeca4a6

MonoMethod *
mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, gboolean aot)
{

if (check_exceptions)
emit_thread_interrupt_checkpoint (mb);

It looks like it would do the thread interruption regardless of the GC state?

static void
emit_thread_interrupt_checkpoint_call (MonoMethodBuilder *mb, MonoJitICallId checkpoint_icall_id)
{
int pos_noabort, pos_noex;
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_LDPTR_INT_REQ_FLAG);
mono_mb_emit_byte (mb, CEE_LDIND_U4);
pos_noabort = mono_mb_emit_branch (mb, CEE_BRFALSE);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_NOT_TAKEN);
mono_mb_emit_icall_id (mb, checkpoint_icall_id);
/* Throw the exception returned by the checkpoint function, if any */
mono_mb_emit_byte (mb, CEE_DUP);
pos_noex = mono_mb_emit_branch (mb, CEE_BRFALSE);
mono_mb_emit_byte (mb, CEE_DUP);
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoException, caught_in_unmanaged));
mono_mb_emit_byte (mb, CEE_LDC_I4_1);
mono_mb_emit_byte (mb, CEE_STIND_I4);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_RETHROW);
mono_mb_patch_branch (mb, pos_noex);
mono_mb_emit_byte (mb, CEE_POP);
mono_mb_patch_branch (mb, pos_noabort);
}

Not sure how this can work in the JIT then. Anyway, we specifically ask to not do generate those checks when building the wrapper for interpreter uses:

virtual_method = mono_marshal_get_native_wrapper (virtual_method, FALSE, FALSE);

target_method = mono_marshal_get_native_wrapper (target_method, FALSE, FALSE);

child_frame.imethod = mono_interp_get_imethod (frame->imethod->domain, mono_marshal_get_native_wrapper (child_frame.imethod->method, FALSE, FALSE), error);

Edit: and in transform.c:
target_method = mono_marshal_get_native_wrapper (target_method, FALSE, FALSE);

target_method = mono_marshal_get_native_wrapper (target_method, FALSE, FALSE);

nm = mono_marshal_get_native_wrapper (method, FALSE, FALSE);

@lewurm
Copy link
Contributor Author

lewurm commented Sep 25, 2019

@monojenkins squash

@monojenkins monojenkins merged commit c81b6f5 into mono:master Sep 26, 2019
ManickaP pushed a commit to ManickaP/runtime that referenced this pull request Jan 20, 2020
…mono#17016)

[interp] always require GC Unsafe mode in exception checkpoint

Follow-up for mono/mono#16955

/cc @BrzVlad 


Commit migrated from mono/mono@c81b6f5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants