[Mono-dev] [PATCH] Implement guarded finally blocks

Paolo Molaro lupus at ximian.com
Fri Mar 26 11:49:51 EDT 2010


On 03/24/10 Rodrigo Kumpera wrote:
> --- a/mono/mini/mini-exceptions.c
> +++ b/mono/mini/mini-exceptions.c
[...]
> +static gboolean
> +find_last_handler_block (MonoDomain *domain, MonoContext *ctx, MonoJitInfo *ji, gpointer data)
> +{
> +	int i;
> +	gpointer ip;
> +	FindHandlerBlockData *pdata = data;
> +
> +	if (ji->method->wrapper_type)
> +		return FALSE;
> +
> +	ip = MONO_CONTEXT_GET_IP (ctx);
> +
> +	for (i = 0; i < ji->num_clauses; ++i) {
> +		MonoJitExceptionInfo *ei = ji->clauses + i;
> +		if (ei->flags != MONO_EXCEPTION_CLAUSE_FINALLY)
> +			continue;
> +		/*If ip points to the first instruction it means the handler block didn't start
> +		 so we can leave its execution to the EH machinery*/
> +		if (ei->handler_start < ip && ip < ei->data.handler_end) {
> +			pdata->ji = ji;
> +			pdata->ei = ei;
> +			pdata->ctx = *ctx;
> +			break;

Shouldn't the stack walk be interrupted here once we found the finally
clause?

> --- a/mono/mini/mini-posix.c
> +++ b/mono/mini/mini-posix.c
> @@ -189,7 +190,15 @@ SIG_HANDLER_SIGNATURE (sigusr1_signal_handler)
>  
>  	if (mono_debugger_agent_thread_interrupt (ctx, ji))
>  		return;
> -	
> +
> +	/* We can't do handler block checking from metadata since it requires doing
> +	 * a stack walk with context.
> +	 */
> +	mono_arch_sigctx_to_monoctx (ctx, &mctx);
> +	if (mono_install_handler_block_guard (thread, &mctx)) {
> +		return;
> +	}
> +#

Leftover here.

> --- a/mono/mini/mini-x86.c
> +++ b/mono/mini/mini-x86.c
> @@ -5809,6 +5809,70 @@ mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *long_ins)
>  #endif /* MONO_ARCH_SIMD_INTRINSICS */
>  }
>  
> +/*MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD*/
> +gpointer
> +mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoContext *ctx, gpointer new_value)
> +{
> +	int i;
> +	int offset;
> +	MonoJitExceptionInfo *clause = NULL;
> +	gpointer ip, *sp, old_value;
> +	char *bp;
> +	const unsigned char *handler;
> +
> +	ip = MONO_CONTEXT_GET_IP (ctx);
> +
> +	for (i = 0; i < ji->num_clauses; ++i) {
> +		clause = &ji->clauses [i];
> +		if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY)
> +			continue;
> +		if (clause->handler_start < ip && clause->data.handler_end > ip)
> +			break;
> +	}
> +
> +	/*no matching finally */
> +	if (i == ji->num_clauses)
> +		return NULL;
> +
> +	/*If we stopped on the instruction right before the try, we haven't actually started executing it*/
> +	if (ip == clause->handler_start)
> +		return NULL;
> +

Up to here there is nothing that is arch-specific. All this code should
be moved to the caller.

The rest of the changes look fine to me.
You might need to disable this code with aot, since I'm not sure the
complete clause data is saved in that case for this to work: did you
test it already? Or the aot changes would need to be implemented, anyway

Thanks!

lupus

-- 
-----------------------------------------------------------------
lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better


More information about the Mono-devel-list mailing list