[llvm-commits] [llvm] r91939 - in /llvm/trunk: lib/ExecutionEngine/JIT/JIT.cpp unittests/ExecutionEngine/JIT/JITTest.cpp

Jeffrey Yasskin jyasskin at google.com
Tue Dec 22 15:18:18 PST 2009


Author: jyasskin
Date: Tue Dec 22 17:18:18 2009
New Revision: 91939

URL: http://llvm.org/viewvc/llvm-project?rev=91939&view=rev
Log:
Fix a crash in JIT::recompileAndRelinkFunction(). It doesn't pass the MCI
argument to runJITOnFunction(), which caused a null pointer dereference at
every call.

Patch by Gianluca Guida!

Modified:
    llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
    llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=91939&r1=91938&r2=91939&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Tue Dec 22 17:18:18 2009
@@ -611,11 +611,13 @@
     }
   };
   MCIListener MCIL(MCI);
-  RegisterJITEventListener(&MCIL);
+  if (MCI)
+    RegisterJITEventListener(&MCIL);
 
   runJITOnFunctionUnlocked(F, locked);
 
-  UnregisterJITEventListener(&MCIL);
+  if (MCI)
+    UnregisterJITEventListener(&MCIL);
 }
 
 void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) {

Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=91939&r1=91938&r2=91939&view=diff

==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Dec 22 17:18:18 2009
@@ -534,6 +534,37 @@
 #endif
 }
 
+TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
+  Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context),
+                                 GlobalValue::ExternalLinkage, "test", M);
+  BasicBlock *Entry = BasicBlock::Create(Context, "entry", F);
+  IRBuilder<> Builder(Entry);
+  Value *Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 1);
+  Builder.CreateRet(Val);
+
+  TheJIT->DisableLazyCompilation(true);
+  // Compile the function once, and make sure it works.
+  int (*OrigFPtr)() = reinterpret_cast<int(*)()>(
+    (intptr_t)TheJIT->recompileAndRelinkFunction(F));
+  EXPECT_EQ(1, OrigFPtr());
+
+  // Now change the function to return a different value.
+  Entry->eraseFromParent();
+  BasicBlock *NewEntry = BasicBlock::Create(Context, "new_entry", F);
+  Builder.SetInsertPoint(NewEntry);
+  Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 2);
+  Builder.CreateRet(Val);
+  // Recompile it, which should produce a new function pointer _and_ update the
+  // old one.
+  int (*NewFPtr)() = reinterpret_cast<int(*)()>(
+    (intptr_t)TheJIT->recompileAndRelinkFunction(F));
+
+  EXPECT_EQ(2, NewFPtr())
+    << "The new pointer should call the new version of the function";
+  EXPECT_EQ(2, OrigFPtr())
+    << "The old pointer's target should now jump to the new version";
+}
+
 }  // anonymous namespace
 // This variable is intentionally defined differently in the statically-compiled
 // program from the IR input to the JIT to assert that the JIT doesn't use its





More information about the llvm-commits mailing list