[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