0

Are there any JVM instructions which are guaranteed not to throw?

If I understand correctly, the spec more or less says that a VirtualMachineError may be thrown at any time. So these two methods may not necessarily behave the same in all situations:

int foo() {
  try { return 1; }
  catch (Throwable t) { return 2; }
}

int bar() { return 1; }

Are there any cases (except if the try block is empty) where the behavior is guaranteed to stay the same after removing a try-catch?

Lukas Rytz
  • 1,894
  • 14
  • 27
  • possible duplicate of [No-throw VirtualMachineError guarantees](http://stackoverflow.com/questions/8728866/no-throw-virtualmachineerror-guarantees) – Raedwald Nov 21 '14 at 12:24

2 Answers2

1

You are asking the wrong question. If you expect a VirtualMachineError to be thrown, you can’t expect the behavior to be guaranteed to stay the same, regardless of whether there is a try … catch or not.

To stay at your example:

try { return 1; }
catch (Throwable t) { return 2; }

For this code, there will be an exception handler for the two byte code instructions iload_1, ireturn. This implies that if a VirtualMachineError is raised right before the iload_1 instruction or right after the JVM encountered the ireturn instruction, the error won’t be catched. And nobody can tell apart that situation from the situation when the the exception handler has been removed and the error is raised in-between these instructions.

Compare with The Java® Virtual Machine Specification, Java SE 8 Edition §2.10. Exceptions:

A Java Virtual Machine may permit a small but bounded amount of execution to occur before an asynchronous exception is thrown. This delay is permitted to allow optimized code to detect and throw these exceptions at points where it is practical to handle them while obeying the semantics of the Java programming language.

So for the case of the VirtualMachineError, the absence of the exception handler would make no difference, no one can notice it and the JVM might defer the error anyway depending on the internal state of code optimization. A different case is the possibility of ireturn throwing an IllegalMonitorStateException.

After all, the question is what you are going to optimize. Exception handlers normally have no performance impact as the JVM doesn’t touch them as long as no exception is there to be handled.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thanks for the answer, Holger, very helpful! Reading the chapter "2.10. Exceptions", it seems not all `VirtualMachineError` are asynchronous. Specifically, a synchronous exception is thrown when the execution of an instruction "Causes some limit on a resource to be exceeded, for example when too much memory is used". So, it seems that almost any instruction may cause such an exception to be thrown - or how could you be sure that an `iload` never causes an `OutOfMemoryError`? – Lukas Rytz Oct 09 '14 at 13:27
  • `iload` only manipulates the current, pre-allocated stack frame. The stack frame is allocated on method invocation and it’s the task of the verifier to ensure that no instruction can exceed the declared stack frame size. So an `iload` can not cause an `OutOfMemoryError`. See [§2.6. Frames](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6) – Holger Oct 09 '14 at 14:44
  • Thanks for following up, really helpful! – Lukas Rytz Oct 10 '14 at 12:43
0

Theoratically everything can throw an exception. But that kind of exceptions aren't treatable anyway, you might as well let the exception stop your application.

Juru
  • 1,623
  • 17
  • 43
  • 1
    Thanks. I'm asking more as a compiler writer: is it safe to eliminate such a handler? I guess the answer is no. – Lukas Rytz Oct 02 '14 at 11:51
  • 1
    @Lukas Well the behavior of virtual machine errors and asynchronous exceptions is obviously implementation dependent, so I wouldn't worry about it. Go ahead and do optimizations if you want (as long as you don't care about debugging) – Antimony Oct 02 '14 at 15:21