incubator-kato-spec mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stuart Monteith <stuk...@stoo.me.uk>
Subject Re: JavaStackFrame/JavaLocation local variable support
Date Mon, 18 May 2009 16:47:21 GMT
Hi,
    I've been looking at local variables in relation to the JDI 
connector. For the BOF at JavaOne we'd like for there to be a prototype 
of  local variable support in the API. I've been looking at what JDWP 
requires as we would have to be able to satisfy its queries using the 
Kato API. This has made me lean towards exposing the variable table and 
have us retrieve the local variables from the stack frames by slot number.

So my suggestion for the API is this:

---------------------------------

JavaMethod
-------------

// returns all local variables
// empty if there are no variables.
Iterator<JavaVariable> getVariable() throws DataUnavailable;

JavaVariable
-------------

// Local variable's name
// throws DataUnavailable if the variable was derived from bytecode and 
so the name is unknown. Caller is free to make a name up.
String getName() throws DataUnavailable;

// The local variable's signature in JNI format.
String getSignature();

// The start of the local variable's scope within the bytecode.
int getStart();

// The number of bytes this variables scope covers over the bytecode.
int getLength();

// The slot this variable occupies. Passed to 
JavaStackFrame.getVariable() to retrieve the contents.
int getSlot();


JavaStackFrame
------------------

// Gets the value of a variable from a stack frame.
// Returns a JavaObject for an object reference, null for a null object 
reference. Primitives are returned as boxed primitives.
// throws CorruptDataException if object reference is incorrect, or if 
the float or double are set to invalid values.
// throws DataUnavailable if this method is not supported or if stack 
not in correct state to return variables.
// throws IndexOutOfBoundsException if an invalid slot number if passed.
Object getVariable(int slot) throws CorruptDataException, 
DataUnavailable, IndexOutOfBoundsException;


---------------------------------

The bytecode offset can be calculated with:
    JavaLocation.getAddress() - ( 
JavaMethod.getBytecodeSections().next().getBase().getAddress())
but I think that might be a little too tedious, and doesn't allow 
cleverness with JITted frames. So we will probably have to add:

// Return program counter in bytecode.
int JavaLocation.getBytecodePC();

alternatively the JavaVariable.getStart() would use absolute addresses, 
which could conceivably work with JITed frames, if the tables are 
maintained during compilation.

We should also expose the line number table too as that will aid class 
file reproduction and queries for line numbers based on bytecode program 
counters.

A slightly different scheme would have the 
JavaStackFrame.getVariable(int slot) method look like:
    Object getVariable(JavaVariable var);
but I don't think it gains us much.

Retrieving all of the variables would therefore look something like this:

void dumpVariables(JavaThread thread) throws Exception {
    Iterator frames = thread.getStackFrames();
    while (frames.hasNext()) {
       JavaStackFrame frame = (JavaStackFrame) frames.next();
       JavaLocation location = frame.getLocation();
       JavaMethod method = location.getMethod();
       int pc = location.getBytecodePC();
      
       System.out.println(location.toString()+":");

       Iterator variables = method.getVariables();
       while (variables.hasNext()) {
          JavaVariable variable = (JavaVariable) variables.next();

          if (pc >= variable.getStart() && pc <= 
variable.getStart()+variables.getLength()) {
             Object value = frame.getVariable( variable.getSlot());
            
             System.out.println("\t"+ variable.getSignature()+" 
"+variable.getName()+" = "+ value.toString());
          }
       }
    }
}

Let me know what you think,
    Stuart

Stuart Monteith wrote:
> Hello,
>    With Steve's work on JVMTI/python coming along, the issue of what 
> to do about local methods is coming up. Currently there is no means to 
> determine the names and values of local variables through the current 
> API.
>
> The most obvious way of implementing this is to have the API do all of 
> the processing by exposing the variables as name and value pairs.
>
> For example:
> interface JavaStackFrame {
>    List<LocalVariable> getLocalVariables();
> }
>
> where:
>
> interface LocalVariable {
>    String getName();
>    Object getValue();
> }
>
> Where the value is a JavaObject, or an boxed primitive.
>
> The other extreme is for the necessary information to be made 
> available for the callers of the API to generate this information 
> themselves.
> This would mean properly exposing:
>    Program Counter - currently we have JavaLocation.getAddress(), 
> which is an address in memory, rather than a bytecode program counter. 
> For JITted frames we'd still need the bytecode program counter.
>    Local variable table - this is to determine which variables there 
> are, their types and their indexes into the local variable array
>    Local variable array - the contents of the local variables need to 
> be exposed, and their proper types should be returnable (JavaObject, 
> int, etc).
>
> Doing it that way might be beneficial for more user stories, there is 
> more information available to reconstruct the class file, for instance.
> There is also the small matter of what to do when the local variable 
> table is not available. When the API exposes all that it knows the 
> values might still be retrievable, although I have my doubts as to how 
> useful that would be if you don't know the types.
>
> Thoughts?
>    Stuart
>

Mime
View raw message