FYI: Faster AccessController stack decoder

Gary Benson gbenson@redhat.com
Wed Aug 9 08:38:00 GMT 2006


Hi all,

The stack walking code in VMAccessController.getContext() stops when
it encounters calls to AccessController.doPrivileged(), meaning that
parts of the stack trace are unused.  This commit adds a custom stack
decoder that mirrors this logic such that only the frames which are
used will be decoded.  I've been using Tomcat as a benchmark, and this
commit improves our performance from 1800 to 2100 requests per second.
Sadly this is nowhere near the 5800 we do without a security manager :/

Cheers,
Gary
-------------- next part --------------
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 116011)
+++ ChangeLog	(working copy)
@@ -1,3 +1,14 @@
+2006-08-09  Gary Benson  <gbenson@redhat.com>
+
+	* include/java-stack.h (accesscontrol_trace_fn): Declare.
+	(GetAccessControlStack): Likewise.
+	(GetClassMethodStack): Remove.
+	* stacktrace.cc (accesscontrol_trace_fn): New method.
+	(GetAccessControlStack): Likewise.
+	(GetClassMethodStack): Remove.
+	* java/security/natVMAccessController.cc (getStack): Use
+	GetAccessControlStack.
+
 2006-08-07  Gary Benson  <gbenson@redhat.com>
 
 	PR libgcj/28340:
Index: include/java-stack.h
===================================================================
--- include/java-stack.h	(revision 116011)
+++ include/java-stack.h	(working copy)
@@ -114,6 +114,7 @@
     
   static _Unwind_Reason_Code calling_class_trace_fn (_Jv_UnwindState *state);
   static _Unwind_Reason_Code non_system_trace_fn (_Jv_UnwindState *state);
+  static _Unwind_Reason_Code accesscontrol_trace_fn (_Jv_UnwindState *state);
 
 public:
   static _Jv_StackTrace *GetStackTrace (void);
@@ -124,7 +125,7 @@
   static void GetCallerInfo (jclass checkClass, jclass *, _Jv_Method **);
   static JArray<jclass> *GetClassContext (jclass checkClass);
   static ClassLoader *GetFirstNonSystemClassLoader (void);
-  static JArray<jobjectArray> *GetClassMethodStack (_Jv_StackTrace *trace);
+  static JArray<jobjectArray> *GetAccessControlStack ();
   
 };
 
Index: stacktrace.cc
===================================================================
--- stacktrace.cc	(revision 116011)
+++ stacktrace.cc	(working copy)
@@ -20,6 +20,7 @@
 
 #include <java/lang/Class.h>
 #include <java/lang/Long.h>
+#include <java/security/AccessController.h>
 #include <java/util/ArrayList.h>
 #include <java/util/IdentityHashMap.h>
 #include <gnu/java/lang/MainThread.h>
@@ -535,16 +536,43 @@
   return NULL;
 }
 
+_Unwind_Reason_Code
+_Jv_StackTrace::accesscontrol_trace_fn (_Jv_UnwindState *state)
+{
+  _Jv_StackFrame *frame = &state->frames[state->pos];
+  FillInFrameInfo (frame);
+
+  bool *stopping = (bool *) state->trace_data;
+  if (*stopping)
+    return _URC_NORMAL_STOP;
+  
+  if (frame->klass == &::java::security::AccessController::class$
+      && frame->meth
+      && strcmp (frame->meth->name->chars(), "doPrivileged") == 0)
+    *stopping = true;
+
+  return _URC_NO_REASON;
+}
+
 JArray<jobjectArray> *
-_Jv_StackTrace::GetClassMethodStack (_Jv_StackTrace *trace)
+_Jv_StackTrace::GetAccessControlStack (void)
 {
+  int trace_size = 100;
+  _Jv_StackFrame frames[trace_size];
+  _Jv_UnwindState state (trace_size);
+  state.frames = (_Jv_StackFrame *) &frames;
+  state.trace_function = accesscontrol_trace_fn;
+  bool stopping = false;
+  state.trace_data = (void *) &stopping;
+
+  UpdateNCodeMap();
+  _Unwind_Backtrace (UnwindTraceFn, &state);
+  
   jint length = 0;
 
-  UpdateNCodeMap();
-  for (int i = 0; i < trace->length; i++)
+  for (int i = 0; i < state.pos; i++)
     {
-      _Jv_StackFrame *frame = &trace->frames[i];
-      FillInFrameInfo (frame);
+      _Jv_StackFrame *frame = &state.frames[i];
 
       if (frame->klass && frame->meth)
 	length++;
@@ -560,9 +588,9 @@
   jclass  *c = elements (classes);
   jstring *m = elements (methods);
 
-  for (int i = 0, j = 0; i < trace->length; i++)
+  for (int i = 0, j = 0; i < state.pos; i++)
     {
-      _Jv_StackFrame *frame = &trace->frames[i];
+      _Jv_StackFrame *frame = &state.frames[i];
       if (!frame->klass || !frame->meth)
 	continue;
       c[j] = frame->klass;
Index: java/security/natVMAccessController.cc
===================================================================
--- java/security/natVMAccessController.cc	(revision 116011)
+++ java/security/natVMAccessController.cc	(working copy)
@@ -19,6 +19,5 @@
 JArray<jobjectArray> *
 java::security::VMAccessController::getStack ()
 {
-  _Jv_StackTrace *trace = _Jv_StackTrace::GetStackTrace ();
-  return _Jv_StackTrace::GetClassMethodStack (trace);
+  return _Jv_StackTrace::GetAccessControlStack ();
 }


More information about the Java-patches mailing list