[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