[ecj] Improved VMStackWalker.getCallingClass()
Gary Benson
gbenson@redhat.com
Thu Dec 7 12:40:00 GMT 2006
Hi all,
This commit makes VMStackWalker.getCallingClass() unwind only
as much of the stack as it needs in the cases when it has to.
Cheers,
Gary
-------------- next part --------------
Index: ChangeLog
===================================================================
--- ChangeLog (revision 119614)
+++ ChangeLog (working copy)
@@ -1,3 +1,14 @@
+2006-12-07 Gary Benson <gbenson@redhat.com>
+
+ * include/java-stack.h (stackwalker_trace_fn,
+ GetStackWalkerCallingClass): Declare.
+ * stacktrace.cc (stackwalker_trace_fn,
+ GetStackWalkerCallingClass): New methods.
+ * gnu/classpath/natVMStackWalker.cc
+ (getCallingClass): Use the above.
+ * gnu/classpath/VMStackWalker.java
+ (getCallingClass): Replace with native method.
+
2006-12-06 Tom Tromey <tromey@redhat.com>
PR java/24938:
Index: include/java-stack.h
===================================================================
--- include/java-stack.h (revision 119614)
+++ include/java-stack.h (working copy)
@@ -133,6 +133,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);
+ static _Unwind_Reason_Code stackwalker_trace_fn (_Jv_UnwindState *state);
public:
static _Jv_StackTrace *GetStackTrace (void);
@@ -144,6 +145,7 @@
static ClassLoader *GetFirstNonSystemClassLoader (void);
static jobjectArray GetAccessControlStack ();
static JArray<jclass> *GetStackWalkerStack ();
+ static jclass GetStackWalkerCallingClass ();
friend jclass _Jv_GetMethodDeclaringClass (jmethodID);
friend class gnu::classpath::VMStackWalker;
Index: stacktrace.cc
===================================================================
--- stacktrace.cc (revision 119614)
+++ stacktrace.cc (working copy)
@@ -678,3 +678,78 @@
return result;
}
+
+typedef enum
+ {
+ VMSW_GETCLASSCONTEXT,
+ JLRM_INVOKE_OR_CALLER,
+ CALLER,
+ CALLER_OF_CALLER
+ } gswcc_expect;
+
+struct StackWalkerTraceData
+{
+ gswcc_expect expect;
+ jclass result;
+};
+
+_Unwind_Reason_Code
+_Jv_StackTrace::stackwalker_trace_fn (_Jv_UnwindState *state)
+{
+ StackWalkerTraceData *trace_data = (StackWalkerTraceData *)
+ 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_GETCLASSCONTEXT:
+ JvAssert (
+ frame->klass == &::gnu::classpath::VMStackWalker::class$
+ && strcmp (frame->meth->name->chars(), "getClassContext") == 0);
+ 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:
+ trace_data->result = frame->klass;
+ return _URC_NORMAL_STOP;
+ }
+
+ return _URC_NO_REASON;
+}
+
+jclass
+_Jv_StackTrace::GetStackWalkerCallingClass (void)
+{
+ int trace_size = 100;
+ _Jv_StackFrame frames[trace_size];
+ _Jv_UnwindState state (trace_size);
+ state.frames = (_Jv_StackFrame *) &frames;
+
+ StackWalkerTraceData trace_data;
+ trace_data.expect = VMSW_GETCLASSCONTEXT;
+ trace_data.result = NULL;
+
+ state.trace_function = stackwalker_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 119614)
+++ gnu/classpath/natVMStackWalker.cc (working copy)
@@ -25,6 +25,12 @@
}
jclass
+gnu::classpath::VMStackWalker::getCallingClass(void)
+{
+ return _Jv_StackTrace::GetStackWalkerCallingClass ();
+}
+
+jclass
gnu::classpath::VMStackWalker::getCallingClass(::gnu::gcj::RawData *pc)
{
void *f = _Unwind_FindEnclosingFunction (pc);
@@ -43,11 +49,7 @@
// is an interpreted frame then klass will be null and we need to
// unwind the stack.
if (klass == NULL)
- {
- JArray<jclass> *ctx = getClassContext ();
- if (ctx->length >= 3)
- klass = elements(ctx)[2];
- }
+ klass = _Jv_StackTrace::GetStackWalkerCallingClass ();
return klass;
}
Index: gnu/classpath/VMStackWalker.java
===================================================================
--- gnu/classpath/VMStackWalker.java (revision 119614)
+++ gnu/classpath/VMStackWalker.java (working copy)
@@ -85,13 +85,7 @@
* method. <code>getCallingClass(addr)</code> does not unwind the
* stack, so is therefore more efficient.
*/
- public static Class getCallingClass()
- {
- Class[] ctx = getClassContext();
- if (ctx.length < 3)
- return null;
- return ctx[2];
- }
+ public static native Class getCallingClass();
/**
* Get the class associated with the method invoking the method
More information about the Java-patches
mailing list