[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