[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: profiling questions



Ondrej Lhotak wrote:
On Sun, Mar 02, 2003 at 02:45:31AM -0500, Chris Pickett wrote:
  
Hi.

I'm trying to compute the number of silent stores in a Java program.  A 
silent store occurs when the value stored is identical to the value 
already there.  I have three questions:

Q1) Why does the single variable "y" in the following code get split 
into "b1" and "b2" in the Jimple representation:

public class HelloWorld {
    public static void main(String[] args) {
        int y;
        y = 2;
        y = 2;
    }
}

-->

public class HelloWorld extends java.lang.Object
{

    public void <init>()
    {
        HelloWorld r0;

        r0 := @this: HelloWorld;
        specialinvoke r0.<java.lang.Object: void <init>()>();
        return;
    }

    public static void main(java.lang.String[] )
    {
        java.lang.String[] r0;
        byte b0, b1;

        r0 := @parameter0: java.lang.String[];
        b0 = 2;
        b1 = 2;
        return;
    }
}
    

By default, Soot splits variables according to def-use chains. This is
mostly because of the variables representing stack slots; they are
typically reused many times, and not splitting them would be very
unfortunate for any analysis trying to use Jimple. You can use the
phase option -p jb unsplit-original-locals to get the original locals
back.
  

As an aside, what Soot options and what version of Soot did you use to
get the Jimple above? There is a dead assignment eliminator that is
supposed to get rid of dead assignments. The Jimple I get does not
have them.
  
I just ran the attached program SilentStoreMain.java as java SilentStoreMain --jimple HelloWorld, using Soot 1.2.4.  I realize the example I gave was dead code, I was just trying to show in the simplest way what the problem was.
  
Q2) How can I test whether a variable (register?) has been initialized 
at runtime.  Currently, for the Jimple code:
    

The Java VM spec says that every variable must be provable to be
initialized before it is first used. The code you are producing
reads the variable before it has been initialized, so the VM cannot
prove that it will always be initialized before being read, so it
refuses to run it. Given that any code that may read uninitialized
variables will be rejected by the VM, it seems kind of pointless to
count reads of uninitialized variables, since there will never be any.
  
I actually don't want to do anything if the variable has not been initialized, except to increment the store counter for that variable.  I can't add code to initialize the variable before I test, because if I did it might give a false silent store when really it's just the initialization of a variable.

e.g.

   b0 = 0;
   if b0 != 0 goto label0;
   tmp = <HelloWorld: long silentStoreCounter>;
   tmp = tmp + 1L;
   <HelloWorld: long silentStoreCounter> = tmp;
label0:
   b0 = 0;

should not be a silent store if the original was just

   b0 = 0;

.............

That said, I have it working for static field references and instance field references (as per your suggestion in another email).  How can I get it working for static arrays and instance arrays?

The problem is that the following Java code:

static int[] j;

...

j = new int[10];
j[1] = 5;

produces the following Jimple code for the last statement:

$r0 = <HelloWorld: int[] j>;
$r0[1] = 5;

and when I reach the $r0[1], I don't know how to detect if it is defined as a static array field or a local array field.  I don't have the same problem with:

<HelloWorld: int x> = $i2;

because I can see immediately at this statement that the left is a static field ref.  If there is an easy way to do this, I'll try now, otherwise I'll leave it at the non-array version.

Cheers,
Chris