[vmkit-commits] [vmkit] r69349 - in /vmkit/trunk/lib/JnJVM: Compiler/ExceptionsCheck.inc VMCore/JavaRuntimeJIT.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Fri Apr 17 06:07:11 PDT 2009


Author: geoffray
Date: Fri Apr 17 08:07:09 2009
New Revision: 69349

URL: http://llvm.org/viewvc/llvm-project?rev=69349&view=rev
Log:
Because runtime intrinsics were marked readnone, LLVM was moving things
around it. And the exception check could be moved before the call. We trick
LLVM by using the return value of these runtime intrinsics: these functions
never return null, so if the return value equals to the current exception
(which may be null), then branch to the an exception handler.


Modified:
    vmkit/trunk/lib/JnJVM/Compiler/ExceptionsCheck.inc
    vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp

Modified: vmkit/trunk/lib/JnJVM/Compiler/ExceptionsCheck.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/ExceptionsCheck.inc?rev=69349&r1=69348&r2=69349&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/ExceptionsCheck.inc (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/ExceptionsCheck.inc Fri Apr 17 08:07:09 2009
@@ -19,9 +19,21 @@
     
     BasicBlock* ifNormal = createBasicBlock("no exception block");
   
+    Value* test = 0;
     Constant* zero = module->JavaObjectNullConstant;
-    Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "",
-                               currentBlock);
+
+    // If F is a runtime intrinsic that does not access memory, use a hack
+    // that will prevent LLVM from moving the exception check: runtime
+    // intrinsics return the exception if an exception was raised.
+    if (F == module->InitialisationCheckFunction || 
+        F == module->GetConstantPoolAtFunction ||
+        F == module->GetArrayClassFunction ||
+        F == module->GetClassDelegateeFunction) {
+      test = new BitCastInst(res, module->JavaObjectType, "", currentBlock);
+      test = new ICmpInst(ICmpInst::ICMP_EQ, test, obj, "", currentBlock);
+    } else {
+      test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", currentBlock);
+    }
 
     BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock);
 
@@ -57,9 +69,17 @@
     
     BasicBlock* ifNormal = createBasicBlock("no exception block");
   
+    Value* test = 0;
     Constant* zero = module->JavaObjectNullConstant;
-    Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "",
-                               currentBlock);
+    if (F == module->InitialisationCheckFunction || 
+        F == module->GetConstantPoolAtFunction ||
+        F == module->GetArrayClassFunction ||
+        F == module->GetClassDelegateeFunction) {
+      test = new BitCastInst(res, module->JavaObjectType, "", currentBlock);
+      test = new ICmpInst(ICmpInst::ICMP_EQ, test, obj, "", currentBlock);
+    } else {
+      test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", currentBlock);
+    }
 
     BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock);
  
@@ -95,11 +115,19 @@
     Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock);
     
     BasicBlock* ifNormal = createBasicBlock("no exception block");
-  
+    
+    Value* test = 0;
     Constant* zero = module->JavaObjectNullConstant;
-    Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "",
-                               currentBlock);
-
+    if (F == module->InitialisationCheckFunction || 
+        F == module->GetConstantPoolAtFunction ||
+        F == module->GetArrayClassFunction ||
+        F == module->GetClassDelegateeFunction) {
+      test = new BitCastInst(res, module->JavaObjectType, "", currentBlock);
+      test = new ICmpInst(ICmpInst::ICMP_EQ, test, obj, "", currentBlock);
+    } else {
+      test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", currentBlock);
+    }
+  
     BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock);
   
     if (!currentExceptionBlock->empty()) {
@@ -132,9 +160,17 @@
     
     BasicBlock* ifNormal = createBasicBlock("no exception block");
   
+    Value* test = 0;
     Constant* zero = module->JavaObjectNullConstant;
-    Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "",
-                               currentBlock);
+    if (F == module->InitialisationCheckFunction || 
+        F == module->GetConstantPoolAtFunction ||
+        F == module->GetArrayClassFunction ||
+        F == module->GetClassDelegateeFunction) {
+      test = new BitCastInst(res, module->JavaObjectType, "", currentBlock);
+      test = new ICmpInst(ICmpInst::ICMP_EQ, test, obj, "", currentBlock);
+    } else {
+      test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", currentBlock);
+    }
 
     BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock);
   

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=69349&r1=69348&r2=69349&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Fri Apr 17 08:07:09 2009
@@ -125,6 +125,11 @@
 
   END_NATIVE_EXCEPTION
 
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (void*)obj;
   return res;
 }
 
@@ -164,6 +169,11 @@
 
   END_NATIVE_EXCEPTION
 
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (void*)obj;
   return res;
 }
 
@@ -209,6 +219,11 @@
 
   END_NATIVE_EXCEPTION
 
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (void*)obj;
   return res;
 }
 #endif
@@ -230,7 +245,12 @@
   res = (void*)cl;
 
   END_NATIVE_EXCEPTION
-
+  
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (void*)obj;
   return res;
 }
 
@@ -243,6 +263,12 @@
   cl->initialiseClass(JavaThread::get()->getJVM());
   
   END_NATIVE_EXCEPTION
+
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (UserCommonClass*)obj;
   return cl;
 }
 
@@ -254,7 +280,12 @@
   Jnjvm* vm = JavaThread::get()->getJVM();
   res = cl->getClassDelegatee(vm);
   END_NATIVE_EXCEPTION
-
+  
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return obj;
   return res;
 }
 
@@ -322,6 +353,11 @@
 
   END_NATIVE_EXCEPTION
 
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (UserClassArray*)obj;
   return res;
 }
 





More information about the vmkit-commits mailing list