OSDN Git Service

2007-02-10 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / gnu / classpath / natVMStackWalker.cc
1 // natVMStackWalker.cc
2
3 /* Copyright (C) 2006, 2007  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12 #include <platform.h>
13
14 #include <gcj/cni.h>
15 #include <jvm.h>
16 #include <java-stack.h>
17 #include <gnu/classpath/VMStackWalker.h>
18 #include <gnu/gcj/RawData.h>
19 #include <java/lang/ClassLoader.h>
20 #include <java/lang/Class.h>
21
22 // Return the class of the method that contains PC.
23 // This is a macro not a function, since defining it as one would
24 // introduce an extra frame on the stack.  */
25 #define GET_CALLING_CLASS(PC)                                           \
26 ({                                                                      \
27   void *f = _Unwind_FindEnclosingFunction (PC);                         \
28                                                                         \
29   /* FIXME: it might well be a good idea to cache pc values here in     \
30      order to avoid repeated invocations of                             \
31      _Unwind_FindEnclosingFunction, which is quite expensive.  On the   \
32      other hand, which not simply write a caching version of            \
33      _Unwind_FindEnclosingFunction itself?  That would probably be      \
34      worthwhile.  */                                                    \
35                                                                         \
36   _Jv_StackTrace::UpdateNCodeMap ();                                    \
37   jclass klass = (jclass) _Jv_StackTrace::ncodeMap->get ((jobject) f);  \
38                                                                         \
39   /* If the caller is a compiled frame and the caller of the caller is  \
40      an interpreted frame then klass will be null and we need to        \
41      unwind the stack.  */                                              \
42   if (!klass)                                                           \
43     klass = _Jv_StackTrace::GetStackWalkerCallingClass ();              \
44                                                                         \
45   klass;                                                                \
46  })
47
48 JArray<jclass> *
49 gnu::classpath::VMStackWalker::getClassContext(void)
50 {
51   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
52   JArray<jclass> *result = _Jv_StackTrace::GetStackWalkerStack ();
53   // Prevent GetStackWalkerStack() from being sibcalled.
54   __asm__ __volatile__ ("" : : "g" (result));
55   return result;
56 }
57
58 jclass
59 gnu::classpath::VMStackWalker::getCallingClass(void)
60 {
61   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
62   return _Jv_StackTrace::GetStackWalkerCallingClass ();
63 }
64
65 jclass
66 gnu::classpath::VMStackWalker::getCallingClass(::gnu::gcj::RawData *pc)
67 {
68   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
69   return GET_CALLING_CLASS(pc);
70 }
71
72 ::java::lang::ClassLoader *
73 gnu::classpath::VMStackWalker::getClassLoader(::java::lang::Class *c)
74 {
75   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
76   return c->getClassLoaderInternal ();
77 }
78
79 ::java::lang::ClassLoader *
80 gnu::classpath::VMStackWalker::getCallingClassLoader(void)
81 {
82   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
83   return
84     _Jv_StackTrace::GetStackWalkerCallingClass ()->getClassLoaderInternal ();
85 }
86
87 ::java::lang::ClassLoader *
88 gnu::classpath::VMStackWalker::getCallingClassLoader(::gnu::gcj::RawData *pc)
89 {
90   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
91   return GET_CALLING_CLASS(pc)->getClassLoaderInternal ();
92 }
93
94 ::java::lang::ClassLoader *
95 gnu::classpath::VMStackWalker::firstNonNullClassLoader(void)
96 {
97   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
98   return _Jv_StackTrace::GetStackWalkerFirstNonNullLoader ();
99 }