[vmkit-commits] [vmkit] r86422 - in /vmkit/trunk: include/jnjvm/JnjvmModule.h include/mvm/GC/GC.h include/mvm/JIT.h include/mvm/Threads/Thread.h lib/JnJVM/Compiler/JavaJITCompiler.cpp lib/JnJVM/VMCore/JavaThread.cpp lib/JnJVM/VMCore/JavaThread.h lib/JnJVM/VMCore/Jnjvm.cpp lib/Mvm/CommonThread/Sigsegv.cpp lib/Mvm/CommonThread/ctthread.cpp lib/Mvm/Compiler/JIT.cpp lib/Mvm/Runtime/Object.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sat Nov 7 16:13:49 PST 2009


Author: geoffray
Date: Sat Nov  7 18:13:48 2009
New Revision: 86422

URL: http://llvm.org/viewvc/llvm-project?rev=86422&view=rev
Log:
Revert part of r86388. The stack walker is bugous.


Modified:
    vmkit/trunk/include/jnjvm/JnjvmModule.h
    vmkit/trunk/include/mvm/GC/GC.h
    vmkit/trunk/include/mvm/JIT.h
    vmkit/trunk/include/mvm/Threads/Thread.h
    vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp
    vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp
    vmkit/trunk/lib/Mvm/Compiler/JIT.cpp
    vmkit/trunk/lib/Mvm/Runtime/Object.cpp

Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Sat Nov  7 18:13:48 2009
@@ -499,6 +499,12 @@
 
 };
 
+class JavaJITStackScanner : public mvm::JITStackScanner {
+public:
+  virtual llvm::GCFunctionInfo* IPToGCFunctionInfo(mvm::VirtualMachine* vm,
+                                                   void* ip);
+};
+
 class JavaJITMethodInfo : public mvm::JITMethodInfo {
 protected:
   JavaMethod* meth;
@@ -574,7 +580,7 @@
 #ifdef WITH_LLVM_GCC
   virtual mvm::StackScanner* createStackScanner() {
     if (useCooperativeGC())
-      return new mvm::PreciseStackScanner();
+      return new JavaJITStackScanner();
     
     return new mvm::UnpreciseStackScanner();
   }

Modified: vmkit/trunk/include/mvm/GC/GC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/GC/GC.h?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/GC/GC.h (original)
+++ vmkit/trunk/include/mvm/GC/GC.h Sat Nov  7 18:13:48 2009
@@ -67,7 +67,7 @@
   virtual void scanStack(mvm::Thread* th);
 };
 
-class PreciseStackScanner : public StackScanner {
+class CamlStackScanner : public StackScanner {
 public:
   virtual void scanStack(mvm::Thread* th);
 };

Modified: vmkit/trunk/include/mvm/JIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/JIT.h (original)
+++ vmkit/trunk/include/mvm/JIT.h Sat Nov  7 18:13:48 2009
@@ -202,6 +202,13 @@
    static const char* getHostTriple();
 };
 
+class JITStackScanner : public StackScanner {
+public:
+  virtual void scanStack(mvm::Thread* th);
+  virtual llvm::GCFunctionInfo* IPToGCFunctionInfo(VirtualMachine* vm,
+                                                   void* ip) = 0;
+};
+
 class JITMethodInfo : public MethodInfo {
   llvm::GCFunctionInfo* GCInfo;
 public:

Modified: vmkit/trunk/include/mvm/Threads/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Thread.h (original)
+++ vmkit/trunk/include/mvm/Threads/Thread.h Sat Nov  7 18:13:48 2009
@@ -336,9 +336,10 @@
     return cpt;
   }
 
-  /// printBacktrace - Print the backtrace.
+  /// printBacktraceAfterSignal - Print the backtrace during a signal
+  /// handler.
   ///
-  void printBacktrace();
+  virtual void printBacktraceAfterSignal() {}
 
   /// addresses - The list of return addresses which represent native/app cross
   /// calls.

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Sat Nov  7 18:13:48 2009
@@ -296,6 +296,13 @@
   return res;
 }
 
+llvm::GCFunctionInfo*
+JavaJITStackScanner::IPToGCFunctionInfo(mvm::VirtualMachine* vm, void* ip) {
+  mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+  JavaMethod* method = (JavaMethod*)MI->getMetaInfo();
+  return method->getInfo<LLVMMethodInfo>()->GCInfo;
+}
+
 // Helper function to run an executable with a JIT
 extern "C" int StartJnjvmWithJIT(int argc, char** argv, char* mainClass) {
   llvm::llvm_shutdown_obj X; 

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Sat Nov  7 18:13:48 2009
@@ -312,6 +312,75 @@
 }
 
 
+void JavaThread::printBacktrace() {
+  std::vector<void*>::iterator it = addresses.end();
+  Jnjvm* vm = getJVM();
+
+  assert((mvm::Thread::get() == this || waitOnSP()) &&
+         "No last sp on foreign thread");
+  
+  void** addr = mvm::Thread::get() == this ? (void**)FRAME_PTR() :
+                                             (void**)waitOnSP();
+  assert(addr && "No address to start with");
+
+  void** oldAddr = addr;
+
+  // Loop until we cross the first Java frame.
+  while (it != addresses.begin()) {
+    
+    --it;
+    // Until we hit the last Java frame.
+    do {
+      void* ip = FRAME_IP(addr);
+      mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+      MI->print(ip, addr);
+      oldAddr = addr;
+      addr = (void**)addr[0];
+    } while (oldAddr != (void**)*it && addr != (void**)*it);
+    
+    // Set the iterator to the next native -> Java call.
+    --it;
+
+    // See if we're from JNI.
+    if (*it == 0) {
+      --it;
+      addr = (void**)*it;
+      --it;
+      if (*it == 0) {
+        void* ip = FRAME_IP(addr);
+        mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+        MI->print(ip, addr);
+        addr = (void**)addr[0];
+        continue;
+      }
+    }
+
+    do {
+      void* ip = FRAME_IP(addr);
+      bool isStub = ((unsigned char*)ip)[0] == 0xCE;
+      if (isStub) ip = addr[2];
+      mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+      MI->print(ip, addr);
+      addr = (void**)addr[0];
+      // End walking the stack when we cross a native -> Java call. Here
+      // the iterator points to a native -> Java call. We dereference addr twice
+      // because a native -> Java call always contains the signature function.
+    } while (((void***)addr)[0][0] != *it);
+  }
+
+  while (addr < baseSP && addr < addr[0]) {
+    void* ip = FRAME_IP(addr);
+    mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+    MI->print(ip, addr);
+    addr = (void**)addr[0];
+  }
+
+}
+
+void JavaThread::printBacktraceAfterSignal() {
+  printBacktrace();
+}
+
 JavaObject** JNILocalReferences::addJNIReference(JavaThread* th,
                                                  JavaObject* obj) {
   llvm_gcroot(obj, 0);

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Sat Nov  7 18:13:48 2009
@@ -300,6 +300,16 @@
   ///
   void getJavaFrameContext(std::vector<void*>& context);
 
+  /// printBacktrace - Prints the backtrace of this thread.
+  ///
+  void printBacktrace() __attribute__ ((noinline));
+
+  /// printBacktraceAfterSignal - Prints the backtrace of this thread while
+  /// in a signal handler.
+  ///
+  virtual void printBacktraceAfterSignal() __attribute__ ((noinline));
+
+
 private:
   /// internalClearException - Clear the C++ and Java exceptions
   /// currently pending.

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Sat Nov  7 18:13:48 2009
@@ -1422,7 +1422,7 @@
 public:
 #ifdef WITH_LLVM_GCC
   virtual mvm::StackScanner* createStackScanner() {
-    return new mvm::PreciseStackScanner();
+    return new mvm::CamlStackScanner();
   }
 #endif
 };

Modified: vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp Sat Nov  7 18:13:48 2009
@@ -57,7 +57,7 @@
     fprintf(stderr, "I received a SIGSEGV: either the VM code or an external\n"
                     "native method is bogus. Aborting...\n");
   }
-  th->printBacktrace();
+  th->printBacktraceAfterSignal();
   abort();
   
 #if defined(__i386__)

Modified: vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp Sat Nov  7 18:13:48 2009
@@ -61,29 +61,6 @@
   addresses.push_back(cur);
 }
 
-void Thread::printBacktrace() {
-  mvm::VirtualMachine* vm = MyVM;
-
-  void** addr = mvm::Thread::get() == this ? 
-    (void**)FRAME_PTR() : (void**)waitOnSP();
-  assert(addr && "No address to start with");
-
-  KnownFrame* currentKnownFrame = lastKnownFrame;
-
-  while (addr < baseSP && addr < addr[0]) {
-    
-    if (currentKnownFrame && addr == currentKnownFrame->currentFP) {
-      currentKnownFrame = currentKnownFrame->previousFrame;
-    }
-
-    void* ip = FRAME_IP(addr);
-    mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
-    MI->print(ip, addr);
-    addr = (void**)addr[0];
-  }
-}
-
-
 uintptr_t Thread::baseAddr = 0;
 
 // These could be set at runtime.

Modified: vmkit/trunk/lib/Mvm/Compiler/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Compiler/JIT.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Compiler/JIT.cpp (original)
+++ vmkit/trunk/lib/Mvm/Compiler/JIT.cpp Sat Nov  7 18:13:48 2009
@@ -543,6 +543,70 @@
   }
 }
 
+void JITStackScanner::scanStack(mvm::Thread* th) {
+  std::vector<void*>::iterator it = th->addresses.end();
+  VirtualMachine* vm = th->MyVM;
+
+  void** addr = mvm::Thread::get() == th ? 
+    (void**)FRAME_PTR() : (void**)th->waitOnSP();
+  assert(addr && "No address to start with");
+  void** oldAddr = addr;
+  DEBUG(fprintf(stderr, "%p trace %p\n", (void*)mvm::Thread::get(), (void*)th));
+  DEBUG(th->printBacktraceAfterSignal());
+
+  // Loop until we cross the first Java frame.
+  while (it != th->addresses.begin()) {
+    
+    --it;
+    // Until we hit the last Java frame.
+    do {
+      void* ip = FRAME_IP(addr);
+      mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+      MI->scan(0, ip, addr);
+      oldAddr = addr;
+      addr = (void**)addr[0];
+    } while (oldAddr != (void**)*it && addr != (void**)*it);
+    
+    // Set the iterator to the next native -> Java call.
+    --it;
+
+    // See if we're from JNI.
+    if (*it == 0) {
+      --it;
+      addr = (void**)*it;
+      --it;
+      if (*it == 0) {
+        void* ip = FRAME_IP(addr);
+        mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+        MI->scan(0, ip, addr);
+        addr = (void**)addr[0];
+        continue;
+      }
+    }
+
+    do {
+      void* ip = FRAME_IP(addr);
+      bool isStub = ((unsigned char*)ip)[0] == 0xCE;
+      if (isStub) ip = addr[2];
+      mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+      MI->scan(0, ip, addr);
+      
+      addr = (void**)addr[0];
+      // End walking the stack when we cross a native -> Java call. Here
+      // the iterator points to a native -> Java call. We dereference addr twice
+      // because a native -> Java call always contains the signature function.
+    } while (((void***)addr)[0][0] != *it);
+  }
+
+  while (addr < th->baseSP && addr < addr[0]) {
+    void* ip = FRAME_IP(addr);
+    mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+    MI->scan(0, ip, addr);
+    addr = (void**)addr[0];
+  }
+
+}
+
 void JITMethodInfo::scan(void* TL, void* ip, void* addr) {
   if (GCInfo) {
     DEBUG(llvm::errs() << GCInfo->getFunction().getName() << '\n');

Modified: vmkit/trunk/lib/Mvm/Runtime/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/Object.cpp?rev=86422&r1=86421&r2=86422&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Sat Nov  7 18:13:48 2009
@@ -261,21 +261,59 @@
   return free(obj); 
 }
 
-void PreciseStackScanner::scanStack(mvm::Thread* th) {
-  mvm::VirtualMachine* vm = th->MyVM;
+void CamlStackScanner::scanStack(mvm::Thread* th) {
+  VirtualMachine* vm = th->MyVM;
+  std::vector<void*>::iterator it = th->addresses.end();
+
+  void** addr = mvm::Thread::get() == th ? (void**)FRAME_PTR() :
+                                           (void**)th->waitOnSP();
+  void** oldAddr = addr;
 
-  void** addr = mvm::Thread::get() == th ? 
-    (void**)FRAME_PTR() : (void**)th->waitOnSP();
-  assert(addr && "No address to start with");
-
-  KnownFrame* currentKnownFrame = th->lastKnownFrame;
-
-  while (addr < th->baseSP && addr < addr[0]) {
+  // Loop until we cross the first Java frame.
+  while (it != th->addresses.begin()) {
     
-    if (currentKnownFrame && addr == currentKnownFrame->currentFP) {
-      currentKnownFrame = currentKnownFrame->previousFrame;
+    --it;
+    // Until we hit the last Java frame.
+    do {
+      void* ip = FRAME_IP(addr);
+      mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+      MI->scan(0, ip, addr);
+      oldAddr = addr;
+      addr = (void**)addr[0];
+    } while (oldAddr != (void**)*it && addr != (void**)*it);
+    
+    // Set the iterator to the next native -> Java call.
+    --it;
+
+    // See if we're from JNI.
+    if (*it == 0) {
+      --it;
+      addr = (void**)*it;
+      --it;
+      if (*it == 0) {
+        void* ip = FRAME_IP(addr);
+        mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+        MI->scan(0, ip, addr);
+        addr = (void**)addr[0];
+        continue;
+      }
     }
 
+    do {
+      void* ip = FRAME_IP(addr);
+      bool isStub = ((unsigned char*)ip)[0] == 0xCE;
+      if (isStub) ip = addr[2];
+      mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
+      MI->scan(0, ip, addr);
+      
+      addr = (void**)addr[0];
+      // End walking the stack when we cross a native -> Java call. Here
+      // the iterator points to a native -> Java call. We dereference addr twice
+      // because a native -> Java call always contains the signature function.
+    } while (((void***)addr)[0][0] != *it);
+  }
+
+  while (addr < th->baseSP && addr < addr[0]) {
     void* ip = FRAME_IP(addr);
     mvm::MethodInfo* MI = vm->IPToMethodInfo(ip);
     MI->scan(0, ip, addr);
@@ -283,6 +321,7 @@
   }
 }
 
+
 void UnpreciseStackScanner::scanStack(mvm::Thread* th) {
   register unsigned int  **max = (unsigned int**)(void*)th->baseSP;
   if (mvm::Thread::get() != th) {





More information about the vmkit-commits mailing list