[vmkit-commits] [vmkit] r60539 - in /vmkit/trunk/lib/JnJVM/VMCore: BundleTermination.cpp JavaClass.cpp JavaThread.cpp JavaThread.h Jnjvm.cpp Jnjvm.h JnjvmClassLoader.cpp VirtualTables.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Thu Dec 4 06:30:56 PST 2008
Author: geoffray
Date: Thu Dec 4 08:30:56 2008
New Revision: 60539
URL: http://llvm.org/viewvc/llvm-project?rev=60539&view=rev
Log:
[SERVICE] Better support for service termination.
Modified:
vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaClass.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/JnJVM/VMCore/Jnjvm.h
vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp
vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
Modified: vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp Thu Dec 4 08:30:56 2008
@@ -15,125 +15,108 @@
#include "signal.h"
-#include "execinfo.h"
-
using namespace jnjvm;
-static void* StackTrace[256];
+#if defined(__MACH__) && !defined(__i386__)
+#define FRAME_IP(fp) (fp[2])
+#else
+#define FRAME_IP(fp) (fp[1])
+#endif
-// 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 throwInlineStoppedBundleException() {
+ void** addr = (void**)__builtin_frame_address(0);
+ JavaThread* th = JavaThread::get();
+ FRAME_IP(addr) = (void**)th->replacedEIPs[--th->eipIndex];
+ th->throwException(th->ServiceException);
+}
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
-
+static mvm::Thread* initiator = 0;
+static bool Finished = true;
void terminationHandler(int) {
void** addr = (void**)__builtin_frame_address(0);
- void* baseSP = mvm::Thread::get()->baseSP;
+ mvm::Thread* th = mvm::Thread::get();
+ JnjvmClassLoader* stoppedBundle =
+ (JnjvmClassLoader*)(th->stoppingService->CU);
+ void* baseSP = th->baseSP;
+ bool inStack = false;
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;
+ inStack = true;
+ JavaThread* th = JavaThread::get();
+ th->replacedEIPs[th->eipIndex++] = FRAME_IP(addr);
+ FRAME_IP(addr) = (void**)(uintptr_t)throwInlineStoppedBundleException;
}
}
}
-
- 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();
- }
+ // If the malicious bundle is in the stack, interrupt the thread.
+ if (inStack) {
+ 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();
+ th->lock.unlock();
- }
- break;
- }
}
if (mvm::Thread::get() != initiator) {
lock.lock();
- while (stoppedBundle)
+ while (!Finished)
cond.wait(&lock);
lock.unlock();
- } else {
- fprintf(stderr, "Je suis l'initiateur, je quitte\n");
}
}
void Jnjvm::stopService() {
-
+
+ lock.lock();
+ while (!Finished)
+ cond.wait(&lock);
+
+ Finished = false;
+ lock.unlock();
+
JnjvmClassLoader* bundle = (JnjvmClassLoader*)CU;
bundle->getIsolate()->status = 1;
- stoppedBundle = bundle;
mvm::Thread* th = mvm::Thread::get();
- th->MyVM->memoryLimit = ~0;
+ th->stoppingService = this;
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);
+ cur->stoppingService = this;
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) {
@@ -153,8 +136,11 @@
}
}
}
- stoppedBundle = 0;
- cond.broadcast();*/
+
+ lock.lock();
+ Finished = true;
+ cond.broadcast();
+ lock.unlock();
}
#endif
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Thu Dec 4 08:30:56 2008
@@ -357,6 +357,13 @@
void* JavaMethod::compiledPtr() {
if (code != 0) return code;
else {
+#ifdef SERVICE
+ Jnjvm *vm = classDef->classLoader->getIsolate();
+ if (vm && vm->status == 0) {
+ JavaThread* th = JavaThread::get();
+ th->throwException(th->ServiceException);
+ }
+#endif
classDef->acquire();
if (code == 0) {
code =
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Thu Dec 4 08:30:56 2008
@@ -39,13 +39,19 @@
state = StateRunning;
pendingException = 0;
#ifdef SERVICE
+ eipIndex = 0;
+ replacedEIPs = new void*[100];
if (isolate->upcalls->newThrowable) {
ServiceException = isolate->upcalls->newThrowable->doNew(isolate);
}
#endif
}
-JavaThread::~JavaThread() {}
+JavaThread::~JavaThread() {
+#ifdef SERVICE
+ delete replacedEIPs;
+#endif
+}
// We define these here because gcc compiles the 'throw' keyword
// differently, whether these are defined in a file or not. Since many
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Thu Dec 4 08:30:56 2008
@@ -44,7 +44,11 @@
void print(mvm::PrintBuffer *buf) const;
virtual void TRACER;
- JavaThread() {}
+ JavaThread() {
+#ifdef SERVICE
+ replacedEIPs = 0;
+#endif
+ }
~JavaThread();
JavaThread(JavaObject* thread, JavaObject* vmThread, Jnjvm* isolate);
@@ -108,7 +112,13 @@
#ifdef SERVICE
JavaObject* ServiceException;
+ void** replacedEIPs;
+ uint32_t eipIndex;
#endif
+
+ static bool isJavaThread(mvm::Thread* th) {
+ return ((void**)th)[0] == VT;
+ }
private:
virtual void internalClearException() {
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Thu Dec 4 08:30:56 2008
@@ -933,9 +933,14 @@
sleep(1);
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!");
- ++executingVM->executionTime;
+ if (JavaThread::isJavaThread(cur)) {
+ JavaThread* th = (JavaThread*)cur;
+ if (!(th->StateWaiting)) {
+ mvm::VirtualMachine* executingVM = cur->MyVM;
+ assert(executingVM && "Thread with no VM!");
+ ++executingVM->executionTime;
+ }
+ }
}
}
}
@@ -1001,6 +1006,8 @@
#ifdef SERVICE
memoryLimit = ~0;
executionLimit = ~0;
+ parent = this;
+ status = 1;
#endif
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Thu Dec 4 08:30:56 2008
@@ -334,6 +334,8 @@
#ifdef SERVICE
virtual void stopService();
+ Jnjvm* parent;
+ uint32 status;
#endif
};
Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Thu Dec 4 08:30:56 2008
@@ -255,6 +255,7 @@
if (isolate->appClassLoader) {
isolate = gc_new(Jnjvm)(bootstrapLoader);
isolate->memoryLimit = 4000000;
+ isolate->parent = I->parent;
isolate->CU = this;
mvm::Thread* th = mvm::Thread::get();
mvm::VirtualMachine* OldVM = th->MyVM;
Modified: vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp?rev=60539&r1=60538&r2=60539&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp Thu Dec 4 08:30:56 2008
@@ -114,6 +114,9 @@
void JavaThread::TRACER {
javaThread->MARK_AND_TRACE;
if (pendingException) pendingException->MARK_AND_TRACE;
+#ifdef SERVICE
+ ServiceException->MARK_AND_TRACE;
+#endif
}
void Jnjvm::TRACER {
@@ -141,12 +144,16 @@
TRACE_VECTOR(JavaString*, gc_allocator, bootstrapLoader->strings);
- if (bootstrapThread) {
- bootstrapThread->CALL_TRACER;
- for (JavaThread* th = (JavaThread*)bootstrapThread->next();
- th != bootstrapThread; th = (JavaThread*)th->next())
- th->CALL_TRACER;
+ mvm::Thread* th = th->get();
+ th->CALL_TRACER;
+ for (mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
+ cur = (mvm::Thread*)cur->next()) {
+ cur->CALL_TRACER;
}
+
+#ifdef SERVICE
+ parent->MARK_AND_TRACE;
+#endif
}
void JnjvmClassLoader::TRACER {
More information about the vmkit-commits
mailing list