[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Question re. compilation of exceptions/monitors in Jimple (fwd)
Hello
Jean-Pierre,
I had a second look in the problem and I found that the situation has
nothing to do with RTJ. I believe there is a bug with
SiteInliner/SynchronizeeManager classes that will potentially cause problems to
all applications with synchronized method. Given the fact some implementation
are JDK library methods are synchronised, well, you can say all J2SE/J2ME
apps are potentially compromised by this bug.
I have
tried to reproduce the problem using JDK 1.3.1_01 (soot.Main --app
-soot-classpath c:\java\jdk1.3.1_01\jre\lib\rt.jar;.\ -O -W MEE):, and I managed
to reproduce the bug. The resultant jimple code looks almost identical to your
output.
I have
added some debug printouts in Soot and it shows two instance of method
inlining:
C:\sandbox\soottest\classes>java soot.Main --app --soot-classpath
c:\java\jdk1.3
.1_01\jre\lib\rt.jar;.\ -O -W -J MEE
Soot started on Tue
Apr 30 15:39:47 BST 2002
Adding inline
candiadates in StaticInliner
target: <MEE:
java.lang.Object newInstance(java.lang.Class)>
container: <MEE: void
essai()>
Statement: $r4 = staticinvoke <MEE: java.lang.Object
newInstance(java.lang.Class
)>($r3)
Adding inline
candiadate in StaticInliner
target: <MEE: void
essai()>
container: <MEE: void
main(java.lang.String[])>
Statement: staticinvoke <MEE: void
essai()>()
Transforming
MEE...
Soot finished on Tue Apr 30 15:39:51 BST 2002
Soot has run for 0
min. 4 sec.
In
both cases StaticInliner is inlining a static invokation with a static method in
the same class file (MEE). (Aside: IMO replacing static calls with inline code
does not produce much gain in speed and likely to increase size, and therefore
should not be incldued as a standard optimisation
techniques)
The
bug surfaces when SiteInliner attempts replace the static invokation of
<MEE: newInstance() inside MEE: essai()>.
The
method <MEE: java.lang.Object newInstance(java.lang.Class)> is a
synchronised method. It can potentially throw an exception. When an exception is
thrown inside newInstance() the control is passed back to the caller, but
at the same time the VM would automatically unlock the monitor (since it is a
synchronised method).
This
behaviour is not reproduced in the inlined code. The
SynchronizerManager does not correctly insert monitoexit code prior to the
athrow instructions. See the following commented Jimple fragments for
details:
<For your reference the original newInstance()>
public static synchronized java.lang.Object
newInstance(java.lang.Class ) throws java.lang.InstantiationException,
java.lang.IllegalAccessException
{
java.lang.Class
r0;
java.lang.Object
r2;
java.lang.Throwable
$r3;
r0 := @parameter0:
java.lang.Class;
label0:
r2 = virtualinvoke
r0.<java.lang.Class: java.lang.Object
newInstance()>();
goto
label2;
label1:
$r3 :=
@caughtexception;
throw $r3;
label2:
return
r2;
catch java.lang.Throwable from
label0 to label1 with label1;
}
<the method where inlining takes place>
public static void essai()
{
java.io.PrintStream $r0, $r5,
$r7;
java.lang.String
r1;
java.lang.Class $r3,
$r8;
java.lang.Exception
$r6;
java.lang.Throwable r9,
$r13;
java.lang.Object
r12;
$r0 = <java.lang.System:
java.io.PrintStream out>;
virtualinvoke $r0.<java.io.PrintStream: void
println(java.lang.String)>("Hello");
// The non-optimised version look like
this
// label0:
// $r3
= staticinvoke <java.lang.Class: java.lang.Class
forName(java.lang.String)>("java.lang.Integer");
// $r4
= staticinvoke <MEE: java.lang.Object
newInstance(java.lang.Class)>($r3);
// r1
= (java.lang.String) $r4;
// $r5
= <java.lang.System: java.io.PrintStream out>;
//
virtualinvoke $r5.<java.io.PrintStream: void
println(java.lang.String)>(r1);
label0:
$r3 = staticinvoke
<java.lang.Class: java.lang.Class
forName(java.lang.String)>("java.lang.Integer");
// Soot replaced staticinvoke <MEE: java.lang.Object
newInstance(java.lang.Class)>($r3) with this bunch of
code
$r8 = <MEE: java.lang.Class
class$MEE>;
if $r8 != null goto
label1;
$r8 = staticinvoke <MEE:
java.lang.Class
class$(java.lang.String)>("MEE");
<MEE: java.lang.Class class$MEE> = $r8;
//
<Begin copy from newInstance()>
label1:
// SynchronizerManager
put this in to replace the automatic VM locking
entermonitor $r8;
label2:
r12 = virtualinvoke
$r3.<java.lang.Class: java.lang.Object
newInstance()>();
goto
label4;
label3:
$r13 :=
@caughtexception;
// Synchronizer should put in an exitmonitor
function here but didn't
throw
$r13;
label4:
// SynchronizerManager
put this in to replace the automatic VM unlocking
exitmonitor
$r8;
goto
label6;
//<Finish copy from
newInstance()>
label5:
r9 :=
@caughtexception;
exitmonitor
$r8;
throw r9;
label6:
r1 = (java.lang.String)
r12;
$r5 = <java.lang.System:
java.io.PrintStream out>;
virtualinvoke $r5.<java.io.PrintStream: void
println(java.lang.String)>(r1);
label7:
goto
label9;
label8:
$r6 :=
@caughtexception;
label9:
$r7 =
<java.lang.System: java.io.PrintStream
out>;
virtualinvoke
$r7.<java.io.PrintStream: void
println(java.lang.String)>("Bye");
return;
catch java.lang.Throwable from
label2 to label3 with label3;
catch java.lang.Throwable from label2 to label4 with
label5;
catch java.lang.Exception
from label0 to label7 with label8;
}
I
don't belive this bug is easy to fix. We cannot simply add a monitorexit in
front of every athrow when inlining a synchronized method. Why? because some of
the athrows can be caught again in the same method if there is a suitable
exception block for it. Some heavy duty control flow analysis would be required
to fix this problem properly.
Regards,
Stephen
-----Original Message-----
From:
Jean-Pierre.Talpin@irisa.fr [mailto:Jean-Pierre.Talpin@irisa.fr]
Sent:
30 April 2002 12:43
To: Stephen Cheng;
Bruno.Ledez@irisa.fr
Subject: Re: Question re. compilation of
exceptions/monitors in Jimple (fwd)
Hi
Stephen,
The engineer working on our translator has isolated the Jimple code
generation bug more precisely. I attach his message. It is in
french, ... but the Java programs are in Java :-) Actually, the methods that
are causing incorrect inlining are exactly the one you mention: these dealing
with memory management. The most of the other methods of javax are correctly
inlined. We have no idea for a workaround at the moment. An intuition
would be to force the javax methods that are not correctly inlined in Jimple
to be handle just as ordinary methods (since inlining works in most
cases). Do you have an idea how we could do that?
We are using SOOT in the context of a French funded project (with
Silicomp, Thales, Verimag, etc) in which we are using the synchronous
compilation tool SIGNAL, developped in our project (www.irisa.fr/espresso), to
engineer, verify, optimize multi-threaded real-time Java programs compliant
with the ARINC avionics requirements. I'll make a presentation about that at
the next J consortium meeting in Rennes, ending of June. The idea is to
abstract/translate Java programs into synchronously interacting transition
systems, in order to either or both verify that a multi-threaded program is
deterministic, model-check it, or even compile dynamic scheduling (eg. merging
two concurrent transition systems into one).
Please let me know if you have any idea on a workaround for inlining javax
methods, as it is an important feature for us (to extract transition systems
from Jimple code). We may help to solve it if you do not have time.
Regards,
Jean-Pierre.
Jean-Pierre,I wonder what you are using
Soot for? I am planning to do some stuff with RTJ as well, so I am most
interested in your experience with RTJ and Soot. I wonder whether you find
Soot working correctly with the RTJ constructs like immortal reference, and
scoped reference. I can't really answer your
question re release timeframe, as I am not part of Sable's group. I hope I
have spare time to fix the VTA/CHA/WPO bugs but they are not my top priority
at the moment. I would appreciate if you would keep me posted of your
solution.Thanks,Stephen
Cheng