blob: ca14c53ec4acc285ba3eaa92079454b0ee91d4a9 [file] [log] [blame]
//===--------- JavaThread.cpp - Java thread description -------------------===//
//
// JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/PassManager.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "mvm/JIT.h"
#include "mvm/PrintBuffer.h"
#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
#include "JavaClass.h"
#include "JavaJIT.h"
#include "JavaObject.h"
#include "JavaThread.h"
#include "Jnjvm.h"
#include "JnjvmModuleProvider.h"
using namespace jnjvm;
const unsigned int JavaThread::StateRunning = 0;
const unsigned int JavaThread::StateWaiting = 1;
const unsigned int JavaThread::StateInterrupted = 2;
void JavaThread::print(mvm::PrintBuffer* buf) const {
buf->write("Thread:");
javaThread->print(buf);
}
void JavaThread::destroyer(size_t sz) {
delete perFunctionPasses;
}
JavaThread* JavaThread::get() {
return threadKey->get();
}
extern void AddStandardCompilePasses(llvm::FunctionPassManager*);
JavaThread* JavaThread::allocate(JavaObject* thread, Jnjvm* isolate) {
JavaThread* key = gc_new(JavaThread)();
key->javaThread = thread;
key->isolate = isolate;
key->lock = mvm::Lock::allocNormal();
key->varcond = mvm::Cond::allocCond();
key->interruptFlag = 0;
key->state = StateRunning;
key->self = mvm::Thread::self();
key->pendingException = 0;
key->perFunctionPasses = new llvm::FunctionPassManager(isolate->TheModuleProvider);
key->perFunctionPasses->add(new llvm::TargetData(isolate->module));
AddStandardCompilePasses(key->perFunctionPasses);
return key;
}
JavaObject* JavaThread::currentThread() {
JavaThread* result = get();
if (result != 0)
return result->javaThread;
else
return 0;
}
extern "C" void* __cxa_allocate_exception(unsigned);
extern "C" void __cxa_throw(void*, void*, void*);
void* JavaThread::getException() {
return (void*)((char*)JavaThread::get()->internalPendingException - 8 * sizeof(void*));
}
JavaObject* JavaThread::getJavaException() {
return JavaThread::get()->pendingException;
}
void JavaThread::throwException(JavaObject* obj) {
JavaThread* th = JavaThread::get();
assert(th->pendingException == 0 && "pending exception already there?");
th->pendingException = obj;
void* exc = __cxa_allocate_exception(0);
th->internalPendingException = exc;
__cxa_throw(exc, 0, 0);
}
void JavaThread::throwPendingException() {
JavaThread* th = JavaThread::get();
assert(th->pendingException);
void* exc = __cxa_allocate_exception(0);
th->internalPendingException = exc;
__cxa_throw(exc, 0, 0);
}
void JavaThread::clearException() {
JavaThread* th = JavaThread::get();
th->pendingException = 0;
th->internalPendingException = 0;
}
bool JavaThread::compareException(Class* cl) {
JavaObject* pe = JavaThread::get()->pendingException;
assert(pe && "no pending exception?");
bool val = pe->classOf->subclassOf(cl);
return val;
}
void JavaThread::returnFromNative() {
assert(sjlj_buffers.size());
longjmp((__jmp_buf_tag*)sjlj_buffers.back(), 1);
}