1

I'm working on a simple dynamic language that runs on the JVM. One of the required capabilities is this: only when an exception is thrown, I need to be able to query the local variables for all frames in the call stack at the time the exception is thrown. This capability is not available in standard Java or reflection. Thus I'm looking at the following idea:

  • Write a simple JVMTI shared object in C
  • When an exception gets thrown in Java-land, trigger a JVMTI function
  • Code in the JVMTI lib suspends the Java thread that threw the exception, inspects the stack to pull out the locals, stores them somewhere accessible, and resumes the Java thread

Other than in this one scenario, JVMTI would not be used at all. Code could potentially run for days without throwing an exception and I would hope it would run as fast as non-JVMTI enabled code.

So my question is: in the mainstream JVM implementations (ie Oracle), what is the overhead of enabling the JVMTI features I need? For example, would doing so disable JIT'ing?

My best guess of the JVMTI "capabilities" I need is:

  • can_signal_thread
  • can_get_source_file_name
  • can_get_source_debug_extension
  • can_access_local_variables
0xbe5077ed
  • 4,565
  • 6
  • 35
  • 77

1 Answers1

0

JVMTI capabilities you mentioned will not prevent from JIT compilation. However certain optimizations will be disabled, e.g. Escape Analysis and dead locals elimination.
Also every thrown exception will cause deoptimization (switching to interpreter).
Nevertheless, overall performance overhead should be negligible.

apangin
  • 92,924
  • 10
  • 193
  • 247
  • why do you say every thrown exception will cause a switch to the interpreter? – 0xbe5077ed Jun 10 '14 at 05:51
  • If you are going to handle exceptions by JVMTI function, you'll have to set up Exception callback. Whenever exception occurs JVM will deoptimize current frame and call this callback. Or were you planning to do that some other way? – apangin Jun 10 '14 at 12:58
  • no you're absolutely right. I found what seemed to be a more direct way, though, by creating a "dummy" function and using JVMTI to set a breakpoint in the dummy function. When I instantiate a particular class of exception, its constructor calls the dummy and that triggers JVMTI to walk the stack and decorate the exception with the local variables info. – 0xbe5077ed Jun 10 '14 at 16:05