SandMark version 3.0


sandmark.watermark.ct.trace
Class Preprocessor

java.lang.Object
  |
  +--sandmark.watermark.ct.trace.Preprocessor

public class Preprocessor
extends java.lang.Object


Field Summary
static int ADDEDCODESIZE
          The amount of code we're adding to each method.
(package private)  ClassFileCollection cfc
           
static java.lang.String FRAMECOUNTER
          Name of static variable in sandmark.watermark.ct.trace.Annotator that holds the current stack ID count.
(package private)  java.util.Properties props
           
static java.lang.String STACKID
          Name of the local variable stored in each method to record the unique ID of that call frame.
 
Constructor Summary
Preprocessor(java.util.Properties props)
           
 
Method Summary
 void preprocess()
          Go through every method in every class of the program and add the code long sm$stackID = sandmark.watermark.ct.trace.Annotator.stackFrameNumber++; to the very beginning of the method.
(package private)  void preprocessClass(EditedClass ec)
          Make the modifications to every method of the class.
(package private)  void preprocessMethod(EditedClass ec, de.fub.bytecode.generic.MethodGen mg)
          Create a local variable to hold the stack ID.
 void save()
          Save the edited classfiles under a new name.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

cfc

ClassFileCollection cfc

props

java.util.Properties props

STACKID

public static final java.lang.String STACKID
Name of the local variable stored in each method to record the unique ID of that call frame.

See Also:
Constant Field Values

FRAMECOUNTER

public static final java.lang.String FRAMECOUNTER
Name of static variable in sandmark.watermark.ct.trace.Annotator that holds the current stack ID count.

See Also:
Constant Field Values

ADDEDCODESIZE

public static final int ADDEDCODESIZE
The amount of code we're adding to each method. Use this to compute the actual offset of a mark() call within the unprocessed (original) source. We're adding the following code, whose size adds up to 11:
   GETSTATIC   X                        3
   DUP2                                 1
   LCONST_1                             1
   LADD                                 1
   GETSTATIC   X                        3
   LSTORE_1    X   (or LSTORE)          1 (or 2)
   (NOP)                                0 (or 1)
 

See Also:
Constant Field Values
Constructor Detail

Preprocessor

public Preprocessor(java.util.Properties props)
             throws java.io.IOException
Method Detail

preprocess

public void preprocess()
                throws java.io.IOException
Go through every method in every class of the program and add the code
    long sm$stackID = sandmark.watermark.ct.trace.Annotator.stackFrameNumber++;
 
to the very beginning of the method. This will give every stackframe a unique ID.

java.io.IOException

save

public void save()
          throws java.io.IOException
Save the edited classfiles under a new name.

java.io.IOException

preprocessClass

void preprocessClass(EditedClass ec)
Make the modifications to every method of the class.

Parameters:
ec - the class to be edited

preprocessMethod

void preprocessMethod(EditedClass ec,
                      de.fub.bytecode.generic.MethodGen mg)
Create a local variable to hold the stack ID.

Parameters:
ec - the class to be edited
mg - the method to be edited Example:
    void P() {
       ...
    }
 
The resulting method would look something like this:
    void P() {
       long sm$stackID = sandmark.watermark.ct.trace.Annotator.stackFrameNumber++;
       ...
    }
 
Or, in bytecode:
   GETSTATIC   sandmark.watermark.ct.trace.Annotator.stackFrameNumber
   DUP2
   LCONST_1
   LADD
   GETSTATIC   sandmark.watermark.ct.trace.Annotator.stackFrameNumber
   LSTORE      sm$stackID-index
 
One complication:
   LSTORE
 
could either be
      LSTORE_1
 
or
      LSTORE 5
 
In the former case the instruction is 1 byte, in the latter, 2. We want all code sequences we insert to be the same length, so that when mark() is called in the preprocessed bytecode, we can figure out what its "real" offset is (the offset in the unprocessed code). Therefore we add an extra NOP in the case of LSTORE_1.

SandMark version 3.0

Wed Jan 29 10:30:05 MST 2003