[vmkit-commits] [vmkit] r69890 - in /vmkit/trunk: include/jnjvm/JnjvmModule.h include/mvm/JIT.h include/mvm/Threads/Thread.h lib/JnJVM/Classpath/ClasspathReflect.h lib/JnJVM/Classpath/ClasspathVMThrowable.cpp lib/JnJVM/Compiler/JavaJIT.cpp lib/JnJVM/Compiler/JnjvmModule.cpp lib/JnJVM/LLVMRuntime/runtime-default.ll lib/JnJVM/VMCore/JavaRuntimeJIT.cpp lib/JnJVM/VMCore/Jnjvm.cpp lib/JnJVM/VMCore/Jnjvm.h lib/Mvm/Compiler/JIT.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Thu Apr 23 07:29:21 PDT 2009
Author: geoffray
Date: Thu Apr 23 09:29:04 2009
New Revision: 69890
URL: http://llvm.org/viewvc/llvm-project?rev=69890&view=rev
Log:
Implement stack overflow checks in Java code.
Modified:
vmkit/trunk/include/jnjvm/JnjvmModule.h
vmkit/trunk/include/mvm/JIT.h
vmkit/trunk/include/mvm/Threads/Thread.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp
vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
vmkit/trunk/lib/Mvm/Compiler/JIT.cpp
Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Thu Apr 23 09:29:04 2009
@@ -333,6 +333,7 @@
llvm::Function* IndexOutOfBoundsExceptionFunction;
llvm::Function* ClassCastExceptionFunction;
llvm::Function* OutOfMemoryErrorFunction;
+ llvm::Function* StackOverflowErrorFunction;
llvm::Function* NegativeArraySizeExceptionFunction;
llvm::Function* ArrayStoreExceptionFunction;
llvm::Function* ArithmeticExceptionFunction;
Modified: vmkit/trunk/include/mvm/JIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/JIT.h (original)
+++ vmkit/trunk/include/mvm/JIT.h Thu Apr 23 09:29:04 2009
@@ -152,6 +152,7 @@
static llvm::Constant* constantPtrNull;
static llvm::ConstantInt* constantPtrSize;
static llvm::ConstantInt* constantThreadIDMask;
+ static llvm::ConstantInt* constantStackOverflowMask;
static llvm::ConstantInt* constantFatMask;
static llvm::ConstantInt* constantPtrOne;
static llvm::ConstantInt* constantPtrZero;
Modified: vmkit/trunk/include/mvm/Threads/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/Threads/Thread.h (original)
+++ vmkit/trunk/include/mvm/Threads/Thread.h Thu Apr 23 09:29:04 2009
@@ -185,6 +185,12 @@
///
static const uint64_t IDMask = 0x7FF00000;
+ /// OverflowMask - Apply this mask to implement overflow checks. For
+ /// efficiency, we lower the available size of the stack: it can never go
+ /// under 0xC0000
+ ///
+ static const uint64_t StackOverflowMask = 0xC0000;
+
/// operator new - Allocate the Thread object as well as the stack for this
/// Thread. The thread object is inlined in the stack.
///
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h Thu Apr 23 09:29:04 2009
@@ -17,6 +17,8 @@
#include <JavaClass.h>
#include <JavaObject.h>
+extern "C" jnjvm::JavaObject* internalFillInStackTrace(jnjvm::JavaObject*);
+
namespace jnjvm {
class JavaObjectClass : public JavaObject {
@@ -130,6 +132,22 @@
};
+
+class JavaObjectThrowable : public JavaObject {
+private:
+ JavaObject* detailedMessage;
+ JavaObject* cause;
+ JavaObject* stackTrace;
+ JavaObject* vmState;
+
+public:
+ void fillInStackTrace() {
+ cause = this;
+ vmState = internalFillInStackTrace(this);
+ stackTrace = 0;
+ }
+};
+
}
#endif
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp Thu Apr 23 09:29:04 2009
@@ -27,17 +27,7 @@
extern "C" {
-JNIEXPORT jobject JNICALL Java_java_lang_VMThrowable_fillInStackTrace(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-jobject throwable) {
-
- jobject res = 0;
-
- BEGIN_NATIVE_EXCEPTION(0)
-
+JavaObject* internalFillInStackTrace(JavaObject* throwable) {
JavaThread* th = JavaThread::get();
Jnjvm* vm = th->getJVM();
@@ -51,7 +41,21 @@
JavaObject* vmThrowable = vm->upcalls->newVMThrowable->doNew(vm);
uint64 ptr = (uint64)vmThrowable + vm->upcalls->vmDataVMThrowable->ptrOffset;
((JavaObject**)ptr)[0] = (JavaObject*)stack;
- res = (jobject)vmThrowable;
+ return vmThrowable;
+}
+
+JNIEXPORT jobject JNICALL Java_java_lang_VMThrowable_fillInStackTrace(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+jobject throwable) {
+
+ jobject res = 0;
+
+ BEGIN_NATIVE_EXCEPTION(0)
+
+ res = (jobject)internalFillInStackTrace((JavaObject*)throwable);
END_NATIVE_EXCEPTION
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Thu Apr 23 09:29:04 2009
@@ -761,6 +761,7 @@
objectLocals.push_back(new AllocaInst(module->JavaObjectType, "",
currentBlock));
}
+
uint32 index = 0;
uint32 count = 0;
@@ -878,8 +879,30 @@
endNode = llvm::PHINode::Create(returnType, "", endBlock);
}
+
+
if (isSynchro(compilingMethod->access))
beginSynchronize();
+
+ // Variables have been allocated and the lock has been taken. Do the stack
+ // check now: if there is an exception, we will go to the lock release code.
+ currentExceptionBlock = opcodeInfos[0].exceptionBlock;
+ Value* FrameAddr = CallInst::Create(module->llvm_frameaddress,
+ module->constantZero, "", currentBlock);
+ FrameAddr = new PtrToIntInst(FrameAddr, module->pointerSizeType, "",
+ currentBlock);
+ Value* stackCheck =
+ BinaryOperator::CreateAnd(FrameAddr, module->constantStackOverflowMask, "",
+ currentBlock);
+
+ stackCheck = new ICmpInst(ICmpInst::ICMP_EQ, stackCheck,
+ module->constantPtrZero, "", currentBlock);
+ BasicBlock* stackOverflow = createBasicBlock("stack overflow");
+ BasicBlock* noStackOverflow = createBasicBlock("no stack overflow");
+ BranchInst::Create(stackOverflow, noStackOverflow, stackCheck, currentBlock);
+ currentBlock = stackOverflow;
+ throwException(module->StackOverflowErrorFunction, 0, 0);
+ currentBlock = noStackOverflow;
compileOpcodes(&compilingClass->bytes->elements[start], codeLen);
Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Thu Apr 23 09:29:04 2009
@@ -374,6 +374,7 @@
NegativeArraySizeExceptionFunction =
module->getFunction("jnjvmNegativeArraySizeException");
OutOfMemoryErrorFunction = module->getFunction("jnjvmOutOfMemoryError");
+ StackOverflowErrorFunction = module->getFunction("jnjvmStackOverflowError");
ArrayStoreExceptionFunction = module->getFunction("jnjvmArrayStoreException");
ArithmeticExceptionFunction = module->getFunction("jnjvmArithmeticException");
Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Thu Apr 23 09:29:04 2009
@@ -215,6 +215,7 @@
declare %JavaObject* @jnjvmIndexOutOfBoundsException(%JavaObject*, i32)
declare %JavaObject* @jnjvmNegativeArraySizeException(i32)
declare %JavaObject* @jnjvmOutOfMemoryError(i32)
+declare %JavaObject* @jnjvmStackOverflowError()
declare %JavaObject* @jnjvmArrayStoreException(%VT*)
declare %JavaObject* @jnjvmArithmeticException()
declare void @jnjvmThrowException(%JavaObject*)
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Thu Apr 23 09:29:04 2009
@@ -480,6 +480,26 @@
}
// Creates a Java object and then throws it.
+extern "C" JavaObject* jnjvmStackOverflowError() {
+ JavaObject *exc = 0;
+ JavaThread *th = JavaThread::get();
+
+ BEGIN_NATIVE_EXCEPTION(1)
+
+ exc = th->getJVM()->CreateStackOverflowError();
+
+ END_NATIVE_EXCEPTION
+
+#ifdef DWARF_EXCEPTIONS
+ th->throwException(exc);
+#else
+ th->pendingException = exc;
+#endif
+
+ return exc;
+}
+
+// Creates a Java object and then throws it.
extern "C" JavaObject* jnjvmArithmeticException() {
JavaObject *exc = 0;
JavaThread *th = JavaThread::get();
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Thu Apr 23 09:29:04 2009
@@ -330,6 +330,13 @@
"Java heap space");
}
+JavaObject* Jnjvm::CreateStackOverflowError() {
+ // Don't call init, or else we'll get a new stack overflow error.
+ JavaObject* obj = upcalls->StackOverflowError->doNew(this);
+ ((JavaObjectThrowable*)obj)->fillInStackTrace();
+ return obj;
+}
+
JavaObject* Jnjvm::CreateArrayStoreException(JavaVirtualTable* VT) {
return CreateError(upcalls->ArrayStoreException,
upcalls->InitArrayStoreException,
@@ -939,8 +946,8 @@
upcalls->uncaughtException->invokeIntSpecial(this, upcalls->threadGroup,
group, obj, exc);
}catch(...) {
- fprintf(stderr, "Even uncaught exception throwed an exception!\n");
- abort();
+ fprintf(stderr, "Exception in thread \"main\": "
+ "Can not print stack trace.\n");
}
}
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Thu Apr 23 09:29:04 2009
@@ -254,6 +254,7 @@
JavaObject* CreateLinkageError(const char* msg = "");
JavaObject* CreateArrayStoreException(JavaVirtualTable* VT);
JavaObject* CreateArithmeticException();
+ JavaObject* CreateStackOverflowError();
/// Exceptions - These are the only exceptions VMKit will make.
///
Modified: vmkit/trunk/lib/Mvm/Compiler/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Compiler/JIT.cpp?rev=69890&r1=69889&r2=69890&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Compiler/JIT.cpp (original)
+++ vmkit/trunk/lib/Mvm/Compiler/JIT.cpp Thu Apr 23 09:29:04 2009
@@ -117,6 +117,8 @@
constantDoubleMinusZero = ConstantFP::get(Type::DoubleTy, -0.0);
constantFloatMinusZero = ConstantFP::get(Type::FloatTy, -0.0f);
constantThreadIDMask = ConstantInt::get(pointerSizeType, mvm::Thread::IDMask);
+ constantStackOverflowMask =
+ ConstantInt::get(pointerSizeType, mvm::Thread::StackOverflowMask);
constantFatMask = ConstantInt::get(pointerSizeType,
pointerSizeType == Type::Int32Ty ? 0x80000000 : 0x8000000000000000LL);
constantPtrOne = ConstantInt::get(pointerSizeType, 1);
@@ -236,6 +238,7 @@
llvm::Constant* MvmModule::constantPtrNull;
llvm::ConstantInt* MvmModule::constantPtrSize;
llvm::ConstantInt* MvmModule::constantThreadIDMask;
+llvm::ConstantInt* MvmModule::constantStackOverflowMask;
llvm::ConstantInt* MvmModule::constantFatMask;
llvm::ConstantInt* MvmModule::constantPtrOne;
llvm::ConstantInt* MvmModule::constantPtrZero;
More information about the vmkit-commits
mailing list