Hi Paolo,<br><br>I&#39;ve spent some time talking with Zoltan and reading more code from the runtime and I have the follow proposal for fixing the problem.<br>First, the problem is that we must not abort finally blocks, the exception must be thrown right after it ends.<br>

There are two options to fix this.<br><br>One is to patch the return address of a finally clause to jump into runtime code that will handle raising the ThreadAbortException.<br>This is very tricky because we need to store precise unwind information to be able to figure out where that value is. The advantage is<br>

that is doesn&#39;t slow down the fast path.<br><br>The other option is to change how finally clauses work so they make this easier. Zoltan mentioned that we should restore from EH context and use a variable to tell what to do next. The pseudo-code for the fast-path are something like:<br>

<br>Currently:<br>try_body:<br>   ...<br>  call finally<br>  jmp rest_of_function<br>finally:<br>  ...<br>  ret<br>rest_of_function:<br>  ...<br><br>Zoltan&#39;s suggestion:<br><br>try body:<br>  ...  <br>  mov 0, [EBP + ?] //this is the variable that tells to resume unwinding or not<br>
  jmp finally;<br>finally:<br> ...<br> cmp 0, [EBP + ?]<br> jmp_if_zero rest_of_function<br> call resume_unwinding<br>rest_of_function:<br> ...<br><br>Looking at the pseudo code, currently we do 3 branches (call, ret, jmp) with Zoltan&#39;s suggestion<br>

we would do only two (jmp, jz), thou one is conditional. The memory bandwidth is the same,<br>both require one load and one store. Zoltan&#39;s suggestion should result in larger code thou.<br><br>But his suggestion, of course, can be optimized to do a lot better, something like the following<br>

won&#39;t be unusual since ordinary &quot;try {} finally {}&quot; code is laid out sequentialy:<br><br><br>try body:<br>  ...<br>  mov 0, [EBP + ?] //this is the variable that tells to resume unwinding or jump somewhere else<br>
  //no jmp, we just fall thru<br>
finally:<br>  ...<br>  cmp 0, [EBP + ?]<br>  jmp_if_not_zero out_of_line_block<br>rest_of_function:<br>  ...<br><br>out_of_line_block:<br>  call resume_unwinding<br><br><br>The version is faster than what we currently generates and enables us to<br>

trap finally handlers without doing something tricky as return address patching.<br><br>For the cases where we have many leave instructions that target different instructions<br>we can generate either a jump table, a series of tests or set the destination variable to<br>
an offset and use an indirect relative jump. All of those depending on what platform/target<br>we are. (AOT x86 is better served with an indirect rel jump while ARM can always use a<br>jump table).<br><br>From our irc log, you raised a few issues with this approach, first that is might cause<br>
issues with the ppc ABI. This approach is basically the same to how we handle catch<br>
clauses and the later doesn&#39;t seen to have issues.<br><br>You also mentioned that a finally clause can be called in a different stack frame that<br>of its original method. I fail to see how could that happen, specially if we&#39;ll be restoring to it.<br>

<br>I do support Zoltan that this approach is the way to go, but I rather hear your opinion first.<br>Even if it ends up been marginally slower, it has the advantage of been much much simpler,<br>which wins us in development time and reliability.<br>

<br>Thanks,<br>Rodrigo<br><br>