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!

llvm-svn: 91939
This commit is contained in:
Jeffrey Yasskin 2009-12-22 23:18:18 +00:00
parent 801fda871b
commit ad46e4416b
2 changed files with 35 additions and 2 deletions

View File

@ -611,11 +611,13 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) {
}
};
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) {

View File

@ -534,6 +534,37 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
#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