RFC: AccessController merge

Gary Benson gbenson@redhat.com
Fri Jul 28 15:14:00 GMT 2006


Andrew Haley wrote:
> Gary Benson writes:
> > Gary Benson wrote:
> > > Andrew Haley wrote:
> > > > I'm a bit concerned about efficiency.  For one example: OK,
> > > > we walk the stack -- we have to do that -- but we create a
> > > > string for every method name , and the only purpose of doing
> > > > so AFAICS is to compare it with "doPrivileged".  We then throw
> > > > away all of those strings we so laboriously constructed...
> > > 
> > > I see what you mean.  Another thing is that if there is a
> > > doPrivileged there then a chunk of the generated stack trace
> > > will be ignored.  I guess Casey wanted the code he put in
> > > stacktrace.cc to be generic.
> > 
> > Ok, so I'm thinking along the lines of the attached patch to solve
> > these two problems.  I thought I'd throw it out to the list before
> > I sit down and write the native bits in case there's any obvious
> > inefficiences that would make it just as bad.  Does it look ok?
> 
> It's rather minimal.  I was expecting a bit more substance...

It might be minimal but it executes in zero time :)
-------------- next part --------------
Index: java/security/VMAccessController.java
===================================================================
--- java/security/VMAccessController.java	(revision 115793)
+++ java/security/VMAccessController.java	(working copy)
@@ -37,7 +37,9 @@
 package java.security;
 
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
+import gnu.gcj.RawDataManaged;
 
 final class VMAccessController
 {
@@ -180,13 +182,8 @@
 
     inGetContext.set(Boolean.TRUE);
 
-    Object[][] stack = getStack();
-    Class[] classes = (Class[]) stack[0];
-    String[] methods = (String[]) stack[1];
+    Iterator stack = new Stack();
 
-    if (DEBUG)
-      debug("got trace of length " + classes.length);
-
     HashSet domains = new HashSet();
     HashSet seenDomains = new HashSet();
     AccessControlContext context = null;
@@ -197,14 +194,16 @@
     // we don't add any more stack frames. We skip the first three stack
     // frames, since they comprise the calls to getStack, getContext,
     // and AccessController.getContext.
-    for (int i = 3; i < classes.length && privileged < 2; i++)
+    for (int i = 0; stack.hasNext(); i++)
       {
-        Class clazz = classes[i];
-        String method = methods[i];
+        Frame frame = (Frame) stack.next();
+        if (i < 3)
+          continue;
+        Class clazz = frame.clazz;
 
         if (DEBUG)
           {
-            debug("checking " + clazz + "." + method);
+            debug("checking " + clazz);
             // subject to getClassLoader RuntimePermission
             debug("loader = " + clazz.getClassLoader());
           }
@@ -214,8 +213,7 @@
         if (privileged == 1)
           privileged = 2;
 
-        if (clazz.equals (AccessController.class)
-            && method.equals ("doPrivileged"))
+        if (frame.privileged)
           {
             // If there was a call to doPrivileged with a supplied context,
             // return that context. If using JAAS doAs*, it should be 
@@ -272,23 +270,43 @@
   }
 
   /**
-   * Returns a snapshot of the current call stack as a pair of arrays:
-   * the first an array of classes in the call stack, the second an array
-   * of strings containing the method names in the call stack. The two
-   * arrays match up, meaning that method <i>i</i> is declared in class
-   * <i>i</i>. The arrays are clean; it will only contain Java methods,
-   * and no element of the list should be null.
-   *
-   * @return A pair of arrays describing the current call stack. The first
-   *    element is an array of Class objects, and the second is an array
-   *    of Strings comprising the method names.
-   */
-  private static native Object[][] getStack();
-
-  /**
    * Tell whether runtime initialization is complete.
    *
    * @return whether runtime initialization is complete.
    */
   private static native boolean runtimeInitialized();
+
+  private static class Stack implements Iterator
+  {
+    private RawDataManaged trace;
+    private int frame;
+
+    Stack()
+    {
+      fillInStackTrace();
+    }
+
+    private native void fillInStackTrace();
+
+    public native boolean hasNext();
+
+    public native Object next();
+
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  private static class Frame
+  {
+    Class clazz;
+    boolean privileged;
+
+    Frame(Class clazz, boolean privileged)
+    {
+      this.clazz = clazz;
+      this.privileged = privileged;
+    }
+  }
 }


More information about the Java-patches mailing list