[llvm-commits] [llvm] r172214 - in /llvm/trunk: lib/ExecutionEngine/JIT/JITEmitter.cpp unittests/ExecutionEngine/JIT/JITTest.cpp
Eli Bendersky
eliben at google.com
Fri Jan 11 08:33:31 PST 2013
Author: eliben
Date: Fri Jan 11 10:33:30 2013
New Revision: 172214
URL: http://llvm.org/viewvc/llvm-project?rev=172214&view=rev
Log:
Fix bug in exception table allocation (PR13678)
Patch by Michael Muller.
Modified:
llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=172214&r1=172213&r2=172214&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Fri Jan 11 10:33:30 2013
@@ -969,14 +969,24 @@
SavedBufferBegin = BufferBegin;
SavedBufferEnd = BufferEnd;
SavedCurBufferPtr = CurBufferPtr;
+ uint8_t *FrameRegister;
- BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
- ActualSize);
- BufferEnd = BufferBegin+ActualSize;
- EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
- uint8_t *EhStart;
- uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd,
- EhStart);
+ while (true) {
+ BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
+ ActualSize);
+ BufferEnd = BufferBegin+ActualSize;
+ EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
+ uint8_t *EhStart;
+ FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart);
+
+ // If the buffer was large enough to hold the table then we are done.
+ if (CurBufferPtr != BufferEnd)
+ break;
+
+ // Try again with twice as much space.
+ ActualSize = (CurBufferPtr - BufferBegin) * 2;
+ MemMgr->deallocateExceptionTable(BufferBegin);
+ }
MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
FrameRegister);
BufferBegin = SavedBufferBegin;
Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=172214&r1=172213&r2=172214&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Fri Jan 11 10:33:30 2013
@@ -161,7 +161,7 @@
uintptr_t ActualSizeResult;
};
std::vector<StartExceptionTableCall> startExceptionTableCalls;
- virtual uint8_t* startExceptionTable(const Function* F,
+ virtual uint8_t *startExceptionTable(const Function *F,
uintptr_t &ActualSize) {
uintptr_t InitialActualSize = ActualSize;
uint8_t *Result = Base->startExceptionTable(F, ActualSize);
@@ -203,14 +203,21 @@
class JITTest : public testing::Test {
protected:
+ virtual RecordingJITMemoryManager *createMemoryManager() {
+ return new RecordingJITMemoryManager;
+ }
+
virtual void SetUp() {
M = new Module("<main>", Context);
- RJMM = new RecordingJITMemoryManager;
+ RJMM = createMemoryManager();
RJMM->setPoisonMemory(true);
std::string Error;
+ TargetOptions Options;
+ Options.JITExceptionHandling = true;
TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
.setJITMemoryManager(RJMM)
- .setErrorStr(&Error).create());
+ .setErrorStr(&Error)
+ .setTargetOptions(Options).create());
ASSERT_TRUE(TheJIT.get() != NULL) << Error;
}
@@ -297,6 +304,46 @@
#endif // !defined(__arm__) && !defined(__powerpc__)
+// Regression test for a bug. The JITEmitter wasn't checking to verify that
+// it hadn't run out of space while generating the DWARF exception information
+// for an emitted function.
+
+class ExceptionMemoryManagerMock : public RecordingJITMemoryManager {
+ public:
+ virtual uint8_t *startExceptionTable(const Function *F,
+ uintptr_t &ActualSize) {
+ // force an insufficient size the first time through.
+ bool ChangeActualSize = false;
+ if (ActualSize == 0)
+ ChangeActualSize = true;;
+ uint8_t *result =
+ RecordingJITMemoryManager::startExceptionTable(F, ActualSize);
+ if (ChangeActualSize)
+ ActualSize = 1;
+ return result;
+ }
+};
+
+class JITExceptionMemoryTest : public JITTest {
+ protected:
+ virtual RecordingJITMemoryManager *createMemoryManager() {
+ return new ExceptionMemoryManagerMock;
+ }
+};
+
+TEST_F(JITExceptionMemoryTest, ExceptionTableOverflow) {
+ Function *F = Function::Create(TypeBuilder<void(void), false>::get(Context),
+ Function::ExternalLinkage,
+ "func1", M);
+ BasicBlock *Block = BasicBlock::Create(Context, "block", F);
+ IRBuilder<> Builder(Block);
+ Builder.CreateRetVoid();
+ TheJIT->getPointerToFunction(F);
+ ASSERT_TRUE(RJMM->startExceptionTableCalls.size() == 2);
+ ASSERT_TRUE(RJMM->deallocateExceptionTableCalls.size() == 1);
+ ASSERT_TRUE(RJMM->endExceptionTableCalls.size() == 1);
+}
+
int PlusOne(int arg) {
return arg + 1;
}
More information about the llvm-commits
mailing list