classpath
[Top][All Lists]
Advanced

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

proposal: VMStackBrowser


From: Steven Augart
Subject: proposal: VMStackBrowser
Date: Sun, 16 Jan 2005 00:58:23 -0500

I propose adding a new class that may be optionally implemented by the
VM, gnu.classpath.VMStackBrowser.  I say that it is "optional" because
I have here a reference implementation for it that uses the existing
gnu.classpath.VMStackWalker to do all the work:

/* VMStackBrowser.java -- Reference implementation of OPTIONAL
   VM hooks for stack access.
   
   [The Classpath copyright notice can go here]
*/

package gnu.classpath;

/**
 * This optional class provides access to the classes on the Java stack.
 * Use this class to explore the stack.  It is sometimes necessary to
 * find out the current context class loader, and other things like that.

 * <P>
 * This reference implementation works on top of the mandatory VMStackWalker
 * class.  So you can leave it completely alone if you want to.
 * You may be able to improve your VM's efficiency by implementing
 * VMStackBrowser yourself.  It's your choice.
 */

public final class VMStackBrowser
{
  /**
   * Internal storage -- the class context returned by VMStackWalker.
   * */
  private Class[] context;
  /**
   * Where are we in the array address@hidden #context}[]? 
   */
  private int position;

  /**
   * Create a new VMStackBrowser, rooted at the caller's current stack frame.
   * The only exception is if the caller is a method in
   * java.lang.reflect.Method.  Since we can not tell those methods apart (all
   * we know is that the class java.lang.reflect.Method was at the top of the
   * frame), we will skip past it in order to present an interface just like
   * that of address@hidden VMStackWalker}.
   * <p>
   * If your VM has stacks that can be moved by the garbage collector,
   * you may have to turn off GC temporarily here.
   */
  VMStackBrowser()
  {
    context = VMStackWalker.getClassContext();
    resetPosition();
  }

  /** Set our position back to the newly-created state, using the same stack
   * trace we started with.  
   */
  public void resetPosition () {
    // context[0] is us.  Skip it.
    position = 1;

    /* If we were invoked by JNI, then we might be past the top of the
       stack. */
    if (position < context.length) 
      return;

    /* If we were invoked by java.lang.reflect.Method.invoke, then pop up one
     * more, for compatibility with address@hidden 
VMStackWalker#getClassContext}'s
     * behaviour. */ 
    if (context[position] == java.lang.reflect.Method.class)
      ++position;
  }

  /** 
   * @return the class at the current position in our walk; otherwise,
   *     <code>null</code> if we're past the top of the stack.  
   */
  public Class getCurrentClass() 
  {
    if (position < context.length)
      return context[position];
    else
      return null;
  }

  /** Can we go up further and still be at a valid stack location? */
  public boolean hasMoreFrames()
  {
    return (position + 1 < context.length);
  }

  /** Go up a frame. */
  public void up()
  {
    ++position;
  }

  /* If your VM has stacks that can be moved by the garbage collector,
   * such that the address@hidden VMStackBrowser} constructor turns off garbage
   * collection, then turn GC back on again here.
   */
  public void release () {}

}





Here is an example of how it could be used by
java.lang.SecurityManager; note that I have not attempted to compile
this code, so there may be a typo or two:

--- java/lang/SecurityManager.java      7 Jan 2005 15:08:23 -0000       1.26
+++ java/lang/SecurityManager.java      16 Jan 2005 05:45:12 -0000
@@ -39,6 +39,7 @@
 package java.lang;
 
 import gnu.classpath.VMStackWalker;
+import gnu.classpath.VMStackBrowser;
 
 import java.awt.AWTPermission;
 import java.io.File;
@@ -242,10 +243,14 @@
    */
   protected int classDepth(String className)
   {
-    Class[] c = getClassContext();
-    for (int i = 0; i < c.length; i++)
-      if (className.equals(c[i].getName()))
-        return i;
+    VMStackBrowser b = new VMStackBrowser();
+    while (b.hasMoreFrames()) 
+      {
+        if (className.equals(c[i].getName()))
+          b.release();
+          return i;
+      }      
+    b.release();
     return -1;
   }


--Steven Augart

-- 
Jikes RVM, a free, open source, Virtual Machine:
http://oss.software.ibm.com/jikesrvm




reply via email to

[Prev in Thread] Current Thread [Next in Thread]