[Top][All Lists]
[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
- proposal: VMStackBrowser,
Steven Augart <=