[vmkit-commits] [vmkit] r60424 - /vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Dec 2 09:10:34 PST 2008


Author: geoffray
Date: Tue Dec  2 11:10:33 2008
New Revision: 60424

URL: http://llvm.org/viewvc/llvm-project?rev=60424&view=rev
Log:
New file, bundle termination, only used in a SERVICE environment.


Added:
    vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp

Added: vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp?rev=60424&view=auto

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp (added)
+++ vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp Tue Dec  2 11:10:33 2008
@@ -0,0 +1,160 @@
+#ifdef SERVICE
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/Target/TargetJITInfo.h"
+
+#include "../lib/ExecutionEngine/JIT/JIT.h"
+
+#include "JavaThread.h"
+#include "JavaJIT.h"
+#include "Jnjvm.h"
+#include "mvm/VirtualMachine.h"
+#include "mvm/Threads/Cond.h"
+#include "mvm/Threads/Locks.h"
+#include "mvm/JIT.h"
+
+#include "signal.h"
+
+#include "execinfo.h"
+
+using namespace jnjvm;
+
+static void* StackTrace[256];
+
+// PrintStackTrace - In the case of a program crash or fault, print out a stack
+// trace so that the user has an indication of why and where we died.
+//
+// On glibc systems we have the 'backtrace' function, which works nicely, but
+// doesn't demangle symbols.  
+static void PrintStackTrace() {
+  // Use backtrace() to output a backtrace on Linux systems with glibc.
+  int depth = backtrace(StackTrace, 256);
+  backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
+}
+
+
+
+static void throwStoppedBundleException() {
+  void** addr = (void**)__builtin_frame_address(0);
+  fprintf(stderr, "in stopped %p\n", addr);
+  JavaJIT::printBacktrace();
+  PrintStackTrace();
+  fprintf(stderr, "OK\n");
+  JavaThread* th = JavaThread::get();
+  th->throwException(th->ServiceException);
+}
+
+
+static JnjvmClassLoader* stoppedBundle;
+static mvm::LockNormal lock;
+static mvm::Cond cond;
+static mvm::Thread* initiator;
+
+
+#if defined(__MACH__) && !defined(__i386__)
+#define FRAME_IP(fp) (fp[2])
+#else
+#define FRAME_IP(fp) (fp[1])
+#endif
+
+
+void terminationHandler(int) {
+  void** addr = (void**)__builtin_frame_address(0);
+  void* baseSP = mvm::Thread::get()->baseSP;
+  while (addr && addr < baseSP && addr < addr[0]) {
+    addr = (void**)addr[0];
+    void** ptr = (void**)FRAME_IP(addr);
+    JavaMethod* meth = JavaJIT::IPToJavaMethod(ptr);
+    if (meth) {
+      if (meth->classDef->classLoader == stoppedBundle) {
+        fprintf(stderr, "Je change %p!\n", FRAME_IP(addr));
+        JavaJIT::printBacktrace();
+        FRAME_IP(addr) = (void**)(uintptr_t)throwStoppedBundleException;
+      }
+    }
+  }
+  
+  addr = (void**)__builtin_frame_address(0);
+  while (addr && addr < baseSP && addr < addr[0]) {
+    addr = (void**)addr[0];
+    void** ptr = (void**)FRAME_IP(addr);
+    JavaMethod* meth = JavaJIT::IPToJavaMethod(ptr);
+    if (meth) {
+      if (meth->classDef->classLoader != stoppedBundle) {
+        JavaThread* th = JavaThread::get();
+        th->lock.lock();
+        th->interruptFlag = 1;
+
+        // here we could also raise a signal for interrupting I/O
+        if (th->state == JavaThread::StateWaiting) {
+          th->state = JavaThread::StateInterrupted;
+          th->varcond.signal();
+        }
+  
+        th->lock.unlock();
+
+      }
+      break;
+    }
+  }
+
+  if (mvm::Thread::get() != initiator) {
+    lock.lock();
+    while (stoppedBundle)
+      cond.wait(&lock);
+    lock.unlock();
+  } else {
+    fprintf(stderr, "Je suis l'initiateur, je quitte\n");
+  }
+}
+
+
+
+void Jnjvm::stopService() {
+ 
+  JnjvmClassLoader* bundle = (JnjvmClassLoader*)CU;
+  bundle->getIsolate()->status = 1;
+  stoppedBundle = bundle;
+  mvm::Thread* th = mvm::Thread::get();
+  th->MyVM->memoryLimit = ~0;
+  initiator = th;
+  fprintf(stderr, "I am %p\n", th);
+  for(mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
+      cur = (mvm::Thread*)cur->next()) {
+    mvm::VirtualMachine* executingVM = cur->MyVM;
+    assert(executingVM && "Thread with no VM!");
+    fprintf(stderr, "Killing th %p\n", cur);
+    uint32 res = cur->kill(SIGUSR1);
+    assert(res == 0);
+
+  }
+  
+  fprintf(stderr, "Doing it\n");
+  // I have to do it too!
+  terminationHandler(0);
+  fprintf(stderr, "OK! bon ben moi je m'en vais\n");
+  /* 
+  llvm::TargetJITInfo& TJI = ((llvm::JIT*)mvm::MvmModule::executionEngine)->getJITInfo();
+  for (ClassMap::iterator i = bundle->getClasses()->map.begin(), e = bundle->getClasses()->map.end();
+       i!= e; ++i) {
+    Class* cl = i->second->asClass();
+
+    if (cl) {
+      for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
+        if (cl->virtualMethods[i].code) {
+          TJI.replaceMachineCodeForFunction(cl->virtualMethods[i].code, (void*)(uintptr_t)throwStoppedBundleException);
+        }
+      }
+    
+      for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
+        if (cl->staticMethods[i].code) {
+          TJI.replaceMachineCodeForFunction(cl->staticMethods[i].code, (void*)(uintptr_t)throwStoppedBundleException);
+        }
+      }
+    }
+  }
+  stoppedBundle = 0;
+  cond.broadcast();*/
+}
+
+#endif





More information about the vmkit-commits mailing list