[vmkit-commits] [vmkit] r78080 - in /vmkit/trunk: include/mvm/JIT.h lib/JnJVM/Compiler/JavaJIT.cpp lib/JnJVM/Compiler/JavaJITCompiler.cpp lib/JnJVM/Compiler/JnjvmModule.cpp lib/JnJVM/Compiler/JnjvmModuleProvider.cpp lib/Mvm/Compiler/JIT.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Aug 4 10:07:30 PDT 2009


Author: geoffray
Date: Tue Aug  4 12:07:28 2009
New Revision: 78080

URL: http://llvm.org/viewvc/llvm-project?rev=78080&view=rev
Log:
Wrap the llvm JIT lock with an internal VMKit lock. From now on, the JIT lock
can not be used while vmkit is working and potentially using other locks. The
VMKit lock must be held before jitting a function, both in llvm and vmkit.


Modified:
    vmkit/trunk/include/mvm/JIT.h
    vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp
    vmkit/trunk/lib/Mvm/Compiler/JIT.cpp

Modified: vmkit/trunk/include/mvm/JIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=78080&r1=78079&r2=78080&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/JIT.h (original)
+++ vmkit/trunk/include/mvm/JIT.h Tue Aug  4 12:07:28 2009
@@ -169,7 +169,7 @@
    static const llvm::Type* pointerSizeType;
 
    static llvm::ExecutionEngine* executionEngine;
-   static mvm::LockNormal protectEngine;
+   static mvm::LockRecursive protectEngine;
    static llvm::Module *globalModule;
    static llvm::ExistingModuleProvider *globalModuleProvider;
    static llvm::FunctionPassManager* globalFunctionPasses;

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=78080&r1=78079&r2=78080&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Tue Aug  4 12:07:28 2009
@@ -263,7 +263,6 @@
                 UTF8Buffer(compilingClass->name).cString(),
                 UTF8Buffer(compilingMethod->name).cString());
   
-    llvmFunction->setLinkage(GlobalValue::ExternalLinkage);
     return llvmFunction;
   }
   
@@ -466,7 +465,6 @@
               UTF8Buffer(compilingClass->name).cString(),
               UTF8Buffer(compilingMethod->name).cString());
   
-  func->setLinkage(GlobalValue::ExternalLinkage);
   
   return llvmFunction;
 }
@@ -1175,8 +1173,6 @@
   removeUnusedObjects(objectLocals, module, TheCompiler->useCooperativeGC());
   removeUnusedObjects(objectStack, module, TheCompiler->useCooperativeGC());
   
-  func->setLinkage(GlobalValue::ExternalLinkage);
-  
   PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "--> end compiling %s.%s\n",
               UTF8Buffer(compilingClass->name).cString(),
               UTF8Buffer(compilingMethod->name).cString());

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp?rev=78080&r1=78079&r2=78080&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Tue Aug  4 12:07:28 2009
@@ -207,9 +207,8 @@
 }
 
 void* JavaJITCompiler::materializeFunction(JavaMethod* meth) {
-  Function* func = parseFunction(meth);
- 
   mvm::MvmModule::protectIR();
+  Function* func = parseFunction(meth);
   void* res = mvm::MvmModule::executionEngine->getPointerToGlobal(func);
   func->deleteBody();
   mvm::MvmModule::unprotectIR();

Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=78080&r1=78079&r2=78080&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Tue Aug  4 12:07:28 2009
@@ -329,22 +329,23 @@
 Function* JavaLLVMCompiler::parseFunction(JavaMethod* meth) {
   LLVMMethodInfo* LMI = getMethodInfo(meth);
   Function* func = LMI->getMethod();
+  
+  // We are jitting. Take the lock.
+  JnjvmModule::protectIR();
   if (func->hasNotBeenReadFromBitcode()) {
-    // We are jitting. Take the lock.
-    JnjvmModule::protectIR();
-    if (func->hasNotBeenReadFromBitcode()) {
-      JavaJIT jit(this, meth, func);
-      if (isNative(meth->access)) {
-        jit.nativeCompile();
-        JnjvmModule::runPasses(func, JavaNativeFunctionPasses);
-      } else {
-        jit.javaCompile();
-        JnjvmModule::runPasses(func, JnjvmModule::globalFunctionPasses);
-        JnjvmModule::runPasses(func, JavaFunctionPasses);
-      }
+    JavaJIT jit(this, meth, func);
+    if (isNative(meth->access)) {
+      jit.nativeCompile();
+      JnjvmModule::runPasses(func, JavaNativeFunctionPasses);
+    } else {
+      jit.javaCompile();
+      JnjvmModule::runPasses(func, JnjvmModule::globalFunctionPasses);
+      JnjvmModule::runPasses(func, JavaFunctionPasses);
     }
-    JnjvmModule::unprotectIR();
+    func->setLinkage(GlobalValue::ExternalLinkage);
   }
+  JnjvmModule::unprotectIR();
+
   return func;
 }
 

Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp?rev=78080&r1=78079&r2=78080&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp Tue Aug  4 12:07:28 2009
@@ -78,11 +78,29 @@
 bool JnjvmModuleProvider::materializeFunction(Function *F, 
                                               std::string *ErrInfo) {
   
-  if (!(F->hasNotBeenReadFromBitcode())) 
+  // The caller of materializeFunction *must* always hold the JIT lock.
+  // Because we are materializing a function here, we must release the
+  // JIT lock and get the global vmkit lock to be thread-safe.
+  // This prevents jitting the function while someone else is doing it.
+  mvm::MvmModule::executionEngine->lock.release(); 
+  mvm::MvmModule::protectIR();
+
+  // Don't use hasNotBeenReadFromBitcode: materializeFunction is called
+  // by the pass manager, and we don't want another thread to JIT the
+  // function while all passes have not been run.
+  if (!(F->isDeclaration())) {
+    mvm::MvmModule::unprotectIR(); 
+    // Reacquire and go back to the JIT function.
+    mvm::MvmModule::executionEngine->lock.acquire();
     return false;
- 
-  if (mvm::MvmModule::executionEngine->getPointerToGlobalIfAvailable(F))
+  }
+
+  if (mvm::MvmModule::executionEngine->getPointerToGlobalIfAvailable(F)) {
+    mvm::MvmModule::unprotectIR(); 
+    // Reacquire and go back to the JIT function.
+    mvm::MvmModule::executionEngine->lock.acquire();
     return false;
+  }
 
   JavaMethod* meth = Comp->getJavaMethod(F);
   
@@ -95,10 +113,6 @@
   
   void* val = meth->compiledPtr();
 
-
-  if (F->isDeclaration())
-    mvm::MvmModule::executionEngine->updateGlobalMapping(F, val);
- 
   if (isVirtual(meth->access)) {
     LLVMMethodInfo* LMI = JavaLLVMCompiler::getMethodInfo(meth);
     uint64_t offset = dyn_cast<ConstantInt>(LMI->getOffset())->getZExtValue();
@@ -114,6 +128,15 @@
     assert(meth->classDef->isInitializing() && "Class not ready");
   }
 
+  mvm::MvmModule::unprotectIR();
+  
+  // Reacquire to go back to the JIT function.
+  mvm::MvmModule::executionEngine->lock.acquire();
+  
+  if (F->isDeclaration())
+    mvm::MvmModule::executionEngine->updateGlobalMapping(F, val);
+
+
   return false;
 }
 

Modified: vmkit/trunk/lib/Mvm/Compiler/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Compiler/JIT.cpp?rev=78080&r1=78079&r2=78080&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Compiler/JIT.cpp (original)
+++ vmkit/trunk/lib/Mvm/Compiler/JIT.cpp Tue Aug  4 12:07:28 2009
@@ -227,7 +227,7 @@
 llvm::ExistingModuleProvider *MvmModule::globalModuleProvider;
 llvm::FunctionPassManager* MvmModule::globalFunctionPasses;
 llvm::ExecutionEngine* MvmModule::executionEngine;
-mvm::LockNormal MvmModule::protectEngine;
+mvm::LockRecursive MvmModule::protectEngine;
 
 
 uint64 MvmModule::getTypeSize(const llvm::Type* type) {
@@ -236,7 +236,13 @@
 
 void MvmModule::runPasses(llvm::Function* func,
                           llvm::FunctionPassManager* pm) {
+  // Take the lock because the pass manager will call materializeFunction.
+  // Our implementation of materializeFunction requires that the lock is held
+  // by the caller. This is due to LLVM's JIT subsystem where the call to
+  // materializeFunction is guarded.
+  if (executionEngine) executionEngine->lock.acquire();
   pm->run(*func);
+  if (executionEngine) executionEngine->lock.release();
 }
 
 static void addPass(FunctionPassManager *PM, Pass *P) {
@@ -301,15 +307,14 @@
 // codegen'ing a function may also create IR objects.
 void MvmModule::protectIR() {
   if (executionEngine) {
-    mvm::Thread* th = mvm::Thread::get();
-    th->enterUncooperativeCode();
-    executionEngine->lock.acquire();
-    th->leaveUncooperativeCode();
+    protectEngine.lock();
   }
 }
 
 void MvmModule::unprotectIR() {
-  if (executionEngine) executionEngine->lock.release();
+  if (executionEngine) {
+    protectEngine.unlock();
+  }
 }
 
 





More information about the vmkit-commits mailing list