Roland Levillain | fc600dc | 2014-12-02 17:16:31 +0000 | [diff] [blame] | 1 | Exercise a method containing a `try' statement with several |
| 2 | instructions with a `finally' clause but without any `catch' block, |
| 3 | enclosed in a loop. |
| 4 | |
| 5 | When dx processes an integer division (or modulo) enclosing a `try' |
| 6 | block and whose result is assigned to a local value, it is smart |
| 7 | enough not to emit a `div-int' (or `rem-int') instruction when the |
| 8 | divisor is non-null, as it wouldn't be used. However, dx is not |
| 9 | that clever regarding exception handling: if the divisor is known to |
| 10 | be non-null at compile-time (as is the case in this test), it will |
| 11 | still emit a block with the exception catching and rethrowing |
| 12 | mechanism, even if it is not used. |
| 13 | |
| 14 | This used to be a problem for a `try' block followed by a `finally' |
| 15 | clause but with no `catch' block: in that case, the generated Dex code |
| 16 | item would list zero catch block for this method (see |
| 17 | art::CodeItem::tries_size_) and the optimizing compiler would have no |
| 18 | clue that it contains a `try' statement, which it cannot optimize |
| 19 | (yet). With no hint that this method might contain one (or several) |
| 20 | special block(s) related to `catch'-less `try' statement(s), the |
| 21 | optimizing compiler considered this (these) as dead block(s) and |
| 22 | improperly tried to remove its (their) instructions, sometimes |
| 23 | removing instructions used by others instructions, thus triggering |
| 24 | assertions. The optimizing compiler was thus adjusted to remove these |
| 25 | instructions in a proper fashion, by removing them as users first, and |
| 26 | then by suppressing them for good. |