mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
| // natVMStackWalker.cc
 | |
| 
 | |
| /* Copyright (C) 2006, 2007  Free Software Foundation
 | |
| 
 | |
|    This file is part of libgcj.
 | |
| 
 | |
| This software is copyrighted work licensed under the terms of the
 | |
| Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | |
| details.  */
 | |
| 
 | |
| #include <config.h>
 | |
| #include <platform.h>
 | |
| 
 | |
| #include <gcj/cni.h>
 | |
| #include <jvm.h>
 | |
| #include <java-stack.h>
 | |
| #include <gnu/classpath/VMStackWalker.h>
 | |
| #include <gnu/gcj/RawData.h>
 | |
| #include <java/lang/ClassLoader.h>
 | |
| #include <java/lang/Class.h>
 | |
| 
 | |
| #ifndef __ARM_EABI_UNWINDER__
 | |
| // Return the class of the method that contains PC.
 | |
| // This is a macro not a function, since defining it as one would
 | |
| // introduce an extra frame on the stack.  */
 | |
| #define GET_CALLING_CLASS(PC)						\
 | |
| ({									\
 | |
|   void *f = _Unwind_FindEnclosingFunction (PC);				\
 | |
| 									\
 | |
|   /* FIXME: it might well be a good idea to cache pc values here in	\
 | |
|      order to avoid repeated invocations of				\
 | |
|      _Unwind_FindEnclosingFunction, which is quite expensive.  On the	\
 | |
|      other hand, which not simply write a caching version of		\
 | |
|      _Unwind_FindEnclosingFunction itself?  That would probably be	\
 | |
|      worthwhile.  */							\
 | |
| 									\
 | |
|   _Jv_StackTrace::UpdateNCodeMap ();					\
 | |
|   jclass klass = (jclass) _Jv_StackTrace::ncodeMap->get ((jobject) f);	\
 | |
| 									\
 | |
|   /* If the caller is a compiled frame and the caller of the caller is	\
 | |
|      an interpreted frame then klass will be null and we need to	\
 | |
|      unwind the stack.  */						\
 | |
|   if (!klass)								\
 | |
|     klass = _Jv_StackTrace::GetStackWalkerCallingClass ();		\
 | |
| 									\
 | |
|   klass;								\
 | |
|  })
 | |
| #else // __ARM_EABI_UNWINDER__
 | |
| // ARM EABI doesn't support _Unwind_FindEnclosingFunction.
 | |
| #define GET_CALLING_CLASS(PC)				\
 | |
|   (_Jv_StackTrace::GetStackWalkerCallingClass ())
 | |
| #endif
 | |
| 
 | |
| JArray<jclass> *
 | |
| gnu::classpath::VMStackWalker::getClassContext(void)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   JArray<jclass> *result = _Jv_StackTrace::GetStackWalkerStack ();
 | |
|   // Prevent GetStackWalkerStack() from being sibcalled.
 | |
|   __asm__ __volatile__ ("" : : "g" (result));
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| jclass
 | |
| gnu::classpath::VMStackWalker::getCallingClass(void)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   jclass result = _Jv_StackTrace::GetStackWalkerCallingClass ();
 | |
|   __asm__ __volatile__ ("" : : "g" (result));
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| jclass
 | |
| gnu::classpath::VMStackWalker::getCallingClass(::gnu::gcj::RawData *pc)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   jclass result = GET_CALLING_CLASS(pc);
 | |
|   __asm__ __volatile__ ("" : : "g" (result));
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| ::java::lang::ClassLoader *
 | |
| gnu::classpath::VMStackWalker::getClassLoader(::java::lang::Class *c)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   return c->getClassLoaderInternal ();
 | |
| }
 | |
| 
 | |
| ::java::lang::ClassLoader *
 | |
| gnu::classpath::VMStackWalker::getCallingClassLoader(void)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   jclass klass = _Jv_StackTrace::GetStackWalkerCallingClass ();
 | |
|   if (klass)
 | |
|     return klass->getClassLoaderInternal ();
 | |
|   else
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| ::java::lang::ClassLoader *
 | |
| gnu::classpath::VMStackWalker::getCallingClassLoader(::gnu::gcj::RawData *pc)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   jclass klass = GET_CALLING_CLASS(pc);
 | |
|   if (klass)
 | |
|     return klass->getClassLoaderInternal ();
 | |
|   else
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| ::java::lang::ClassLoader *
 | |
| gnu::classpath::VMStackWalker::firstNonNullClassLoader(void)
 | |
| {
 | |
|   _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
 | |
|   return _Jv_StackTrace::GetStackWalkerFirstNonNullLoader ();
 | |
| }
 |