OSDN Git Service

PR target/35496
[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 #ifndef __ARM_EABI_UNWINDER__
23 // Return the class of the method that contains PC.
24 // This is a macro not a function, since defining it as one would
25 // introduce an extra frame on the stack.  */
26 #define GET_CALLING_CLASS(PC)                                           \
27 ({                                                                      \
28   void *f = _Unwind_FindEnclosingFunction (PC);                         \
29                                                                         \
30   /* FIXME: it might well be a good idea to cache pc values here in     \
31      order to avoid repeated invocations of                             \
32      _Unwind_FindEnclosingFunction, which is quite expensive.  On the   \
33      other hand, which not simply write a caching version of            \
34      _Unwind_FindEnclosingFunction itself?  That would probably be      \
35      worthwhile.  */                                                    \
36                                                                         \
37   _Jv_StackTrace::UpdateNCodeMap ();                                    \
38   jclass klass = (jclass) _Jv_StackTrace::ncodeMap->get ((jobject) f);  \
39                                                                         \
40   /* If the caller is a compiled frame and the caller of the caller is  \
41      an interpreted frame then klass will be null and we need to        \
42      unwind the stack.  */                                              \
43   if (!klass)                                                           \
44     klass = _Jv_StackTrace::GetStackWalkerCallingClass ();              \
45                                                                         \
46   klass;                                                                \
47  })
48 #else // __ARM_EABI_UNWINDER__
49 // ARM EABI doesn't support _Unwind_FindEnclosingFunction.
50 #define GET_CALLING_CLASS(PC)                           \
51   (_Jv_StackTrace::GetStackWalkerCallingClass ())
52 #endif
53
54 JArray<jclass> *
55 gnu::classpath::VMStackWalker::getClassContext(void)
56 {
57   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
58   JArray<jclass> *result = _Jv_StackTrace::GetStackWalkerStack ();
59   // Prevent GetStackWalkerStack() from being sibcalled.
60   __asm__ __volatile__ ("" : : "g" (result));
61   return result;
62 }
63
64 jclass
65 gnu::classpath::VMStackWalker::getCallingClass(void)
66 {
67   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
68   jclass result = _Jv_StackTrace::GetStackWalkerCallingClass ();
69   __asm__ __volatile__ ("" : : "g" (result));
70   return result;
71 }
72
73 jclass
74 gnu::classpath::VMStackWalker::getCallingClass(::gnu::gcj::RawData *pc)
75 {
76   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
77   jclass result = GET_CALLING_CLASS(pc);
78   __asm__ __volatile__ ("" : : "g" (result));
79   return result;
80 }
81
82 ::java::lang::ClassLoader *
83 gnu::classpath::VMStackWalker::getClassLoader(::java::lang::Class *c)
84 {
85   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
86   return c->getClassLoaderInternal ();
87 }
88
89 ::java::lang::ClassLoader *
90 gnu::classpath::VMStackWalker::getCallingClassLoader(void)
91 {
92   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
93   jclass klass = _Jv_StackTrace::GetStackWalkerCallingClass ();
94   if (klass)
95     return klass->getClassLoaderInternal ();
96   else
97     return NULL;
98 }
99
100 ::java::lang::ClassLoader *
101 gnu::classpath::VMStackWalker::getCallingClassLoader(::gnu::gcj::RawData *pc)
102 {
103   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
104   jclass klass = GET_CALLING_CLASS(pc);
105   if (klass)
106     return klass->getClassLoaderInternal ();
107   else
108     return NULL;
109 }
110
111 ::java::lang::ClassLoader *
112 gnu::classpath::VMStackWalker::firstNonNullClassLoader(void)
113 {
114   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
115   return _Jv_StackTrace::GetStackWalkerFirstNonNullLoader ();
116 }