[ecj] Improved VMStackWalker.firstNonNullClassLoader()

Gary Benson gbenson@redhat.com
Thu Dec 14 17:08:00 GMT 2006


Hi all,

This commit makes VMStackWalker.firstNonNullClassLoader() unwind
only as much of the stack as is necessary.  I originally made a
second version with a rewritten argument much like all the other
VMStackWalker methods, but decided it was stupid and reverted it.
Now I can't remember why I thought that, so I'll probably remake
and commit it (tomorrow).

Cheers,
Gary
-------------- next part --------------
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 119832)
+++ ChangeLog	(working copy)
@@ -1,3 +1,14 @@
+2006-12-14  Gary Benson  <gbenson@redhat.com>
+
+	* include/java-stack.h (stackwalker_nnl_trace_fn,
+	GetStackWalkerFirstNonNullLoader): Declare.
+	* stacktrace.cc (stackwalker_nnl_trace_fn,
+	GetStackWalkerFirstNonNullLoader): New methods.
+	* gnu/classpath/natVMStackWalker.cc
+	(firstNonNullClassLoader): New method.
+	* gnu/classpath/VMStackWalker.java
+	(firstNonNullClassLoader): Replace with native method.
+
 2006-12-13  Gary Benson  <gbenson@redhat.com>
 
 	* stacktrace.cc (stackwalker_trace_fn,
Index: include/java-stack.h
===================================================================
--- include/java-stack.h	(revision 119820)
+++ include/java-stack.h	(working copy)
@@ -136,6 +136,7 @@
   static _Unwind_Reason_Code non_system_trace_fn (_Jv_UnwindState *state);
   static _Unwind_Reason_Code accesscontrol_trace_fn (_Jv_UnwindState *state);
   static _Unwind_Reason_Code stackwalker_trace_fn (_Jv_UnwindState *state);
+  static _Unwind_Reason_Code stackwalker_nnl_trace_fn (_Jv_UnwindState *state);
 
 public:
   static _Jv_StackTrace *GetStackTrace (void);
@@ -148,6 +149,7 @@
   static jobjectArray GetAccessControlStack ();
   static JArray<jclass> *GetStackWalkerStack ();
   static jclass GetStackWalkerCallingClass ();
+  static ClassLoader *GetStackWalkerFirstNonNullLoader ();
 
   friend jclass _Jv_GetMethodDeclaringClass (jmethodID);
   friend class gnu::classpath::VMStackWalker;
Index: stacktrace.cc
===================================================================
--- stacktrace.cc	(revision 119832)
+++ stacktrace.cc	(working copy)
@@ -751,3 +751,72 @@
 
   return trace_data.result;
 }
+
+struct StackWalkerNNLTraceData
+{
+  gswcc_expect expect;
+  ClassLoader *result;
+};
+
+_Unwind_Reason_Code
+_Jv_StackTrace::stackwalker_nnl_trace_fn (_Jv_UnwindState *state)
+{
+  StackWalkerNNLTraceData *trace_data = (StackWalkerNNLTraceData *)
+    state->trace_data;
+  _Jv_StackFrame *frame = &state->frames[state->pos];
+  FillInFrameInfo (frame);
+
+  if (!(frame->klass && frame->meth))
+    return _URC_NO_REASON;
+
+  switch (trace_data->expect)
+    {
+    case VMSW_GET_CALLING_ITEM:
+      JvAssert (frame->klass == &::gnu::classpath::VMStackWalker::class$);
+      trace_data->expect = JLRM_INVOKE_OR_CALLER;
+      break;
+
+    case JLRM_INVOKE_OR_CALLER:
+      if (frame->klass == &::java::lang::reflect::Method::class$
+	  && strcmp (frame->meth->name->chars(), "invoke") == 0)
+	trace_data->expect = CALLER;
+      else
+	trace_data->expect = CALLER_OF_CALLER;
+      break;
+
+    case CALLER:
+      trace_data->expect = CALLER_OF_CALLER;
+      break;
+
+    case CALLER_OF_CALLER:
+      ClassLoader *cl = frame->klass->getClassLoaderInternal ();
+      if (cl != NULL)
+	{
+	  trace_data->result = cl;
+	  return _URC_NORMAL_STOP;
+	}
+    }
+
+  return _URC_NO_REASON;
+}
+
+ClassLoader *
+_Jv_StackTrace::GetStackWalkerFirstNonNullLoader (void)
+{
+  int trace_size = 100;
+  _Jv_StackFrame frames[trace_size];
+  _Jv_UnwindState state (trace_size);
+  state.frames = (_Jv_StackFrame *) &frames;
+
+  StackWalkerNNLTraceData trace_data;
+  trace_data.expect = VMSW_GET_CALLING_ITEM;
+  trace_data.result = NULL;
+  
+  state.trace_function = stackwalker_nnl_trace_fn;
+  state.trace_data = (void *) &trace_data;
+
+  UpdateNCodeMap();
+  _Unwind_Backtrace (UnwindTraceFn, &state);
+
+  return trace_data.result;
+}
Index: gnu/classpath/natVMStackWalker.cc
===================================================================
--- gnu/classpath/natVMStackWalker.cc	(revision 119832)
+++ gnu/classpath/natVMStackWalker.cc	(working copy)
@@ -73,3 +73,8 @@
   return getCallingClass (pc)->getClassLoaderInternal ();
 }
 
+::java::lang::ClassLoader *
+gnu::classpath::VMStackWalker::firstNonNullClassLoader(void)
+{
+  return _Jv_StackTrace::GetStackWalkerFirstNonNullLoader ();
+}
Index: gnu/classpath/VMStackWalker.java
===================================================================
--- gnu/classpath/VMStackWalker.java	(revision 119832)
+++ gnu/classpath/VMStackWalker.java	(working copy)
@@ -133,16 +133,6 @@
    * Walk up the stack and return the first non-null class loader.
    * If there aren't any non-null class loaders on the stack, return null.
    */
-  public static ClassLoader firstNonNullClassLoader()
-  {
-    Class[] stack = getClassContext();
-    for (int i = 0; i < stack.length; i++)
-      {
-        ClassLoader loader = getClassLoader(stack[i]);
-        if (loader != null)
-          return loader;
-      }
-    return null;
-  }
+  public static native ClassLoader firstNonNullClassLoader();
 }
 


More information about the Java-patches mailing list