Share

ProGuard Java Optimizer and Obfuscator

Tracker: Bugs

6 Fix output with -target 1.1 to workaround old JIT bugs - ID: 2893068
Last Update: Comment added ( lafortune )

All modern Java compilers (Sun JDK compilers since 1.4, gcj, jikes, and
others) add an exception table entry around the monitorexit instruction in
the exception handler for a synchronized block. This triggers a bug in the
JIT compiler used in Sun JRE's up to at least version 1.2, causing the code
to enter an infinite loop, throwing IllegalMonitorStateExceptions. Thus,
code produced with -target 1.1 on all of these compilers cannot actually be
run on the intended target JVMs. Since I cannot actually fix the compilers
in question, and Sun has refused to fix this problem, I've attempted to
modify Proguard to fix their output.

I've attached a patch which removes these exception table entries when the
targetClassVersion is 1.2 or earlier. The instruction in question cannot
actually throw an exception under normal circumstances, unless there was an
error in the original bytecode, or a JNI call somehow corrupted the
internal JVM state, so this can be considered a "code size optimization".
However, as a side-effect, the resulting code actually runs correctly on
the JVMs it was intended for. The patch applies against the Proguard
4.5beta2 tarball. See the URLs in the patch for more background information
on the issue.

My primary use-case is compiling the Cortado applet, which is used to
provide Theora and Vorbis support in very old browsers, some of which still
ship very old JVMs. Since the entire point of this applet is to serve as a
fallback, it is important that it actually works on these old JVMs.


Timothy B. Terriberry ( tterribe ) - 2009-11-06 04:58

6

Open

None

Eric Lafortune

None

None

Public


Comments ( 4 )

Date: 2009-11-07 23:56
Sender: lafortuneProject Admin

Ok, we'll solve it like this. I've removed the MONITOR_EXIT line for the
upcoming ProGuard 4.5 beta3.


Date: 2009-11-07 20:42
Sender: tterribe

I can confirm that just removing that line also produces code that actually
runs.


Date: 2009-11-07 20:26
Sender: tterribe

I assume you mean MONITOREXIT, but yes, I believe that would work. That was
actually the solution proposed by one of my colleagues, but I thought it
better (in light of the aforementioned discussions) to make the minimum
changes required to the class files in order to get them to run correctly.
I'm happy to test any patches.

Another potential source of exceptions in MONITOREXIT is asynchronous
exceptions, i.e., ThreadDeath or an internal JVM error. The former, at
least, has long been deprecated because it could never hope to work
correctly. But the current optimizations will already remove exception
handlers in ways that could affect these.

We also discussed the possibility of duplicating the handler, so that each
one could throw exceptions into the other, thus possibly avoiding the JIT
bug. I haven't confirmed that this would really work around the problem,
but it might be palatable to compiler writers. However, this is no longer
an optimization (it would add 3-5 instructions and another exception table
entry for each synchronized block).


Date: 2009-11-07 20:07
Sender: lafortuneProject Admin

Thanks for the detailed analysis and for the clean code. I would prefer to
handle this as a general optimization, since ProGuard's retargeting does
not attempt to fix any incompatibilities between versions (e.g.
StringBuffer vs StringBuilder). For programs (or at least Java programs)
that are compiled correctly, I would assume that monitorexit cannot throw
exceptions. It's a bit worrying that this goes against the conclusions in
the discussions to which you refer, and against the way Java programs are
currently compiled.

Removing line 94 (opcode == InstructionConstants.OP_MONITORENTER) in
proguard/optimize/info/ExceptionInstructionChecker.java then seems to be
sufficient. Would that work for you?


Attached File ( 1 )

Filename Description Download
proguard4.5beta2-remmonex.patch Download

Changes ( 3 )

Field Old Value Date By
priority 5 2009-11-07 20:07 lafortune
assigned_to nobody 2009-11-07 20:07 lafortune
File Added 349722: proguard4.5beta2-remmonex.patch 2009-11-06 04:58 tterribe