summaryrefslogtreecommitdiffstats
path: root/unittests/ExecutionEngine
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ExecutionEngine')
-rw-r--r--unittests/ExecutionEngine/CMakeLists.txt8
-rw-r--r--unittests/ExecutionEngine/ExecutionEngineTest.cpp10
-rw-r--r--unittests/ExecutionEngine/JIT/CMakeLists.txt3
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp9
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h16
-rw-r--r--unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp12
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp85
-rw-r--r--unittests/ExecutionEngine/JIT/Makefile2
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp8
-rw-r--r--unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp5
-rw-r--r--unittests/ExecutionEngine/MCJIT/CMakeLists.txt4
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp172
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTest.cpp6
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h17
-rw-r--r--unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp143
-rw-r--r--unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h118
-rw-r--r--unittests/ExecutionEngine/Makefile5
17 files changed, 295 insertions, 328 deletions
diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt
index ed7f10a..4eefc1e 100644
--- a/unittests/ExecutionEngine/CMakeLists.txt
+++ b/unittests/ExecutionEngine/CMakeLists.txt
@@ -6,5 +6,9 @@ add_llvm_unittest(ExecutionEngineTests
ExecutionEngineTest.cpp
)
-add_subdirectory(JIT)
-add_subdirectory(MCJIT)
+# Include JIT/MCJIT tests only if native arch is a JIT target.
+list(FIND LLVM_TARGETS_WITH_JIT "${LLVM_NATIVE_ARCH}" have_jit)
+if (NOT have_jit EQUAL -1 )
+ add_subdirectory(JIT)
+ add_subdirectory(MCJIT)
+endif()
diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index 74a2ccd..3e304e7 100644
--- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DerivedTypes.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "gtest/gtest.h"
using namespace llvm;
diff --git a/unittests/ExecutionEngine/JIT/CMakeLists.txt b/unittests/ExecutionEngine/JIT/CMakeLists.txt
index 11cf784..ef37026 100644
--- a/unittests/ExecutionEngine/JIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/JIT/CMakeLists.txt
@@ -19,7 +19,9 @@ if( LLVM_USE_INTEL_JITEVENTS )
)
set(LLVM_LINK_COMPONENTS
${LLVM_LINK_COMPONENTS}
+ DebugInfo
IntelJITEvents
+ Object
)
endif( LLVM_USE_INTEL_JITEVENTS )
@@ -53,3 +55,4 @@ add_llvm_unittest(JITTests
if(MINGW OR CYGWIN)
set_property(TARGET JITTests PROPERTY LINK_FLAGS -Wl,--export-all-symbols)
endif()
+set_target_properties(JITTests PROPERTIES ENABLE_EXPORTS 1)
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
index 333888a..6ba8bc4 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
@@ -8,14 +8,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITEventListener.h"
-
-#include "llvm/LLVMContext.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/TypeBuilder.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include "gtest/gtest.h"
#include <vector>
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
index 5f02b38..d1c2124 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
@@ -10,24 +10,22 @@
#ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
#define JIT_EVENT_LISTENER_TEST_COMMON_H
+#include "llvm/CodeGen/MachineCodeInfo.h"
+#include "llvm/Config/config.h"
#include "llvm/DIBuilder.h"
#include "llvm/DebugInfo.h"
-#include "llvm/IRBuilder.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/TypeBuilder.h"
-#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/Config/config.h"
-
#include "gtest/gtest.h"
-
-#include <vector>
#include <string>
#include <utility>
+#include <vector>
typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
diff --git a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
index be5d152..21ca0d4 100644
--- a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "gtest/gtest.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/LLVMContext.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/LLVMContext.h"
+#include "gtest/gtest.h"
using namespace llvm;
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 59604df..30dadc9 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -7,28 +7,27 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/BasicBlock.h"
-#include "llvm/Constant.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/IRBuilder.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
-#include "llvm/TypeBuilder.h"
+#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
-
#include "gtest/gtest.h"
#include <vector>
@@ -118,13 +117,14 @@ public:
Base->endFunctionBody(F, FunctionStart, FunctionEnd);
}
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) {
- return Base->allocateDataSection(Size, Alignment, SectionID);
+ unsigned SectionID, bool IsReadOnly) {
+ return Base->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
}
virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID) {
return Base->allocateCodeSection(Size, Alignment, SectionID);
}
+ virtual bool applyPermissions(std::string *ErrMsg) { return false; }
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
return Base->allocateSpace(Size, Alignment);
}
@@ -161,7 +161,7 @@ public:
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 @@ bool LoadAssemblyInto(Module *M, const char *assembly) {
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 @@ TEST(JIT, GlobalInFunction) {
#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;
}
diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile
index 9e0bb9e..ef8b827 100644
--- a/unittests/ExecutionEngine/JIT/Makefile
+++ b/unittests/ExecutionEngine/JIT/Makefile
@@ -24,7 +24,7 @@ ifeq ($(USE_INTEL_JITEVENTS), 1)
CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
# Link against the LLVM Intel JIT Evens interface library
- LINK_COMPONENTS += inteljitevents
+ LINK_COMPONENTS += debuginfo inteljitevents object
endif
ifeq ($(USE_OPROFILE), 1)
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
index 4a22e2f..5301467 100644
--- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "gtest/gtest.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
#include <vector>
using namespace llvm;
diff --git a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
index 9b0ee60..7057fca 100644
--- a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
@@ -7,12 +7,11 @@
//
//===--------------------------------------------------------------------------------------===//
-#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/OProfileWrapper.h"
#include "JITEventListenerTestCommon.h"
-
-#include <map>
+#include "llvm/ExecutionEngine/JITEventListener.h"
#include <list>
+#include <map>
using namespace llvm;
diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
index 3e9c5b6..c6b1f77 100644
--- a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
@@ -2,14 +2,14 @@ set(LLVM_LINK_COMPONENTS
asmparser
bitreader
bitwriter
- mcjit
jit
+ mcjit
nativecodegen
)
set(MCJITTestsSources
MCJITTest.cpp
- SectionMemoryManager.cpp
+ MCJITMemoryManagerTest.cpp
)
if(MSVC)
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
new file mode 100644
index 0000000..ab09aca
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
@@ -0,0 +1,172 @@
+//===- MCJITMemoryManagerTest.cpp - Unit tests for the JIT memory manager -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(MCJITMemoryManagerTest, BasicAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t *code1 = MemMgr->allocateCodeSection(256, 0, 1);
+ uint8_t *data1 = MemMgr->allocateDataSection(256, 0, 2, true);
+ uint8_t *code2 = MemMgr->allocateCodeSection(256, 0, 3);
+ uint8_t *data2 = MemMgr->allocateDataSection(256, 0, 4, false);
+
+ EXPECT_NE((uint8_t*)0, code1);
+ EXPECT_NE((uint8_t*)0, code2);
+ EXPECT_NE((uint8_t*)0, data1);
+ EXPECT_NE((uint8_t*)0, data2);
+
+ // Initialize the data
+ for (unsigned i = 0; i < 256; ++i) {
+ code1[i] = 1;
+ code2[i] = 2;
+ data1[i] = 3;
+ data2[i] = 4;
+ }
+
+ // Verify the data (this is checking for overlaps in the addresses)
+ for (unsigned i = 0; i < 256; ++i) {
+ EXPECT_EQ(1, code1[i]);
+ EXPECT_EQ(2, code2[i]);
+ EXPECT_EQ(3, data1[i]);
+ EXPECT_EQ(4, data2[i]);
+ }
+
+ std::string Error;
+ EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+}
+
+TEST(MCJITMemoryManagerTest, LargeAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t *code1 = MemMgr->allocateCodeSection(0x100000, 0, 1);
+ uint8_t *data1 = MemMgr->allocateDataSection(0x100000, 0, 2, true);
+ uint8_t *code2 = MemMgr->allocateCodeSection(0x100000, 0, 3);
+ uint8_t *data2 = MemMgr->allocateDataSection(0x100000, 0, 4, false);
+
+ EXPECT_NE((uint8_t*)0, code1);
+ EXPECT_NE((uint8_t*)0, code2);
+ EXPECT_NE((uint8_t*)0, data1);
+ EXPECT_NE((uint8_t*)0, data2);
+
+ // Initialize the data
+ for (unsigned i = 0; i < 0x100000; ++i) {
+ code1[i] = 1;
+ code2[i] = 2;
+ data1[i] = 3;
+ data2[i] = 4;
+ }
+
+ // Verify the data (this is checking for overlaps in the addresses)
+ for (unsigned i = 0; i < 0x100000; ++i) {
+ EXPECT_EQ(1, code1[i]);
+ EXPECT_EQ(2, code2[i]);
+ EXPECT_EQ(3, data1[i]);
+ EXPECT_EQ(4, data2[i]);
+ }
+
+ std::string Error;
+ EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+}
+
+TEST(MCJITMemoryManagerTest, ManyAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t* code[10000];
+ uint8_t* data[10000];
+
+ for (unsigned i = 0; i < 10000; ++i) {
+ const bool isReadOnly = i % 2 == 0;
+
+ code[i] = MemMgr->allocateCodeSection(32, 0, 1);
+ data[i] = MemMgr->allocateDataSection(32, 0, 2, isReadOnly);
+
+ for (unsigned j = 0; j < 32; j++) {
+ code[i][j] = 1 + (i % 254);
+ data[i][j] = 2 + (i % 254);
+ }
+
+ EXPECT_NE((uint8_t *)0, code[i]);
+ EXPECT_NE((uint8_t *)0, data[i]);
+ }
+
+ // Verify the data (this is checking for overlaps in the addresses)
+ for (unsigned i = 0; i < 10000; ++i) {
+ for (unsigned j = 0; j < 32;j++ ) {
+ uint8_t ExpectedCode = 1 + (i % 254);
+ uint8_t ExpectedData = 2 + (i % 254);
+ EXPECT_EQ(ExpectedCode, code[i][j]);
+ EXPECT_EQ(ExpectedData, data[i][j]);
+ }
+ }
+
+ std::string Error;
+ EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+}
+
+TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t* code[10000];
+ uint8_t* data[10000];
+
+ for (unsigned i = 0; i < 10000; ++i) {
+ uintptr_t CodeSize = i % 16 + 1;
+ uintptr_t DataSize = i % 8 + 1;
+
+ bool isReadOnly = i % 3 == 0;
+ unsigned Align = 8 << (i % 4);
+
+ code[i] = MemMgr->allocateCodeSection(CodeSize, Align, i);
+ data[i] = MemMgr->allocateDataSection(DataSize, Align, i + 10000,
+ isReadOnly);
+
+ for (unsigned j = 0; j < CodeSize; j++) {
+ code[i][j] = 1 + (i % 254);
+ }
+
+ for (unsigned j = 0; j < DataSize; j++) {
+ data[i][j] = 2 + (i % 254);
+ }
+
+ EXPECT_NE((uint8_t *)0, code[i]);
+ EXPECT_NE((uint8_t *)0, data[i]);
+
+ uintptr_t CodeAlign = Align ? (uintptr_t)code[i] % Align : 0;
+ uintptr_t DataAlign = Align ? (uintptr_t)data[i] % Align : 0;
+
+ EXPECT_EQ((uintptr_t)0, CodeAlign);
+ EXPECT_EQ((uintptr_t)0, DataAlign);
+ }
+
+ for (unsigned i = 0; i < 10000; ++i) {
+ uintptr_t CodeSize = i % 16 + 1;
+ uintptr_t DataSize = i % 8 + 1;
+
+ for (unsigned j = 0; j < CodeSize; j++) {
+ uint8_t ExpectedCode = 1 + (i % 254);
+ EXPECT_EQ(ExpectedCode, code[i][j]);
+ }
+
+ for (unsigned j = 0; j < DataSize; j++) {
+ uint8_t ExpectedData = 2 + (i % 254);
+ EXPECT_EQ(ExpectedData, data[i][j]);
+ }
+ }
+}
+
+} // Namespace
+
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
index 6b79a68..e9cf904 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -14,7 +14,6 @@
#include "llvm/ExecutionEngine/MCJIT.h"
#include "MCJITTestBase.h"
-#include "SectionMemoryManager.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -47,6 +46,7 @@ TEST_F(MCJITTest, global_variable) {
GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
createJIT(M.take());
void *globalPtr = TheJIT->getPointerToGlobal(Global);
+ MM->applyPermissions();
static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
EXPECT_TRUE(0 != globalPtr)
<< "Unable to get pointer to global value from JIT";
@@ -61,6 +61,7 @@ TEST_F(MCJITTest, add_function) {
Function *F = insertAddFunction(M.get());
createJIT(M.take());
void *addPtr = TheJIT->getPointerToFunction(F);
+ MM->applyPermissions();
static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
EXPECT_TRUE(0 != addPtr)
<< "Unable to get pointer to function from JIT";
@@ -78,6 +79,7 @@ TEST_F(MCJITTest, run_main) {
Function *Main = insertMainFunction(M.get(), 6);
createJIT(M.take());
void *vPtr = TheJIT->getPointerToFunction(Main);
+ MM->applyPermissions();
static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
EXPECT_TRUE(0 != vPtr)
<< "Unable to get pointer to main() from JIT";
@@ -100,6 +102,7 @@ TEST_F(MCJITTest, return_global) {
createJIT(M.take());
void *rgvPtr = TheJIT->getPointerToFunction(ReturnGlobal);
+ MM->applyPermissions();
static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
EXPECT_TRUE(0 != rgvPtr);
@@ -169,6 +172,7 @@ TEST_F(MCJITTest, multiple_functions) {
createJIT(M.take());
void *vPtr = TheJIT->getPointerToFunction(Outer);
+ MM->applyPermissions();
static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
EXPECT_TRUE(0 != vPtr)
<< "Unable to get pointer to outer function from JIT";
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index 9b4a4ac..fc774ab 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -17,20 +17,19 @@
#ifndef MCJIT_TEST_BASE_H
#define MCJIT_TEST_BASE_H
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/Function.h"
-#include "llvm/IRBuilder.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/TypeBuilder.h"
-
-#include "SectionMemoryManager.h"
// Used to skip tests on unsupported architectures and operating systems.
// To skip a test, add this macro at the top of a test-case in a suite that
@@ -53,7 +52,7 @@ protected:
, MArch("")
, Builder(Context)
, MM(new SectionMemoryManager)
- , HostTriple(LLVM_HOSTTRIPLE)
+ , HostTriple(sys::getProcessTriple())
{
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
deleted file mode 100644
index d6baf3c..0000000
--- a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-//===-- SectionMemoryManager.cpp - The memory manager for MCJIT -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the implementation of the section-based memory manager
-// used by MCJIT.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/MathExtras.h"
-
-#include "SectionMemoryManager.h"
-
-#ifdef __linux__
-// These includes used by SectionMemoryManager::getPointerToNamedFunction()
-// for Glibc trickery. Look comments in this function for more information.
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-namespace llvm {
-
-uint8_t *SectionMemoryManager::allocateDataSection(uintptr_t Size,
- unsigned Alignment,
- unsigned SectionID) {
- if (!Alignment)
- Alignment = 16;
- // Ensure that enough memory is requested to allow aligning.
- size_t NumElementsAligned = 1 + (Size + Alignment - 1)/Alignment;
- uint8_t *Addr = (uint8_t*)calloc(NumElementsAligned, Alignment);
-
- // Honour the alignment requirement.
- uint8_t *AlignedAddr = (uint8_t*)RoundUpToAlignment((uint64_t)Addr, Alignment);
-
- // Store the original address from calloc so we can free it later.
- AllocatedDataMem.push_back(sys::MemoryBlock(Addr, NumElementsAligned*Alignment));
- return AlignedAddr;
-}
-
-uint8_t *SectionMemoryManager::allocateCodeSection(uintptr_t Size,
- unsigned Alignment,
- unsigned SectionID) {
- if (!Alignment)
- Alignment = 16;
- unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1);
- uintptr_t Addr = 0;
- // Look in the list of free code memory regions and use a block there if one
- // is available.
- for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) {
- sys::MemoryBlock &MB = FreeCodeMem[i];
- if (MB.size() >= NeedAllocate) {
- Addr = (uintptr_t)MB.base();
- uintptr_t EndOfBlock = Addr + MB.size();
- // Align the address.
- Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
- // Store cutted free memory block.
- FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size),
- EndOfBlock - Addr - Size);
- return (uint8_t*)Addr;
- }
- }
-
- // No pre-allocated free block was large enough. Allocate a new memory region.
- sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0);
-
- AllocatedCodeMem.push_back(MB);
- Addr = (uintptr_t)MB.base();
- uintptr_t EndOfBlock = Addr + MB.size();
- // Align the address.
- Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
- // The AllocateRWX may allocate much more memory than we need. In this case,
- // we store the unused memory as a free memory block.
- unsigned FreeSize = EndOfBlock-Addr-Size;
- if (FreeSize > 16)
- FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize));
-
- // Return aligned address
- return (uint8_t*)Addr;
-}
-
-void SectionMemoryManager::invalidateInstructionCache() {
- for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
- sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(),
- AllocatedCodeMem[i].size());
-}
-
-void *SectionMemoryManager::getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure) {
-#if defined(__linux__)
- //===--------------------------------------------------------------------===//
- // Function stubs that are invoked instead of certain library calls
- //
- // Force the following functions to be linked in to anything that uses the
- // JIT. This is a hack designed to work around the all-too-clever Glibc
- // strategy of making these functions work differently when inlined vs. when
- // not inlined, and hiding their real definitions in a separate archive file
- // that the dynamic linker can't see. For more info, search for
- // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
- if (Name == "stat") return (void*)(intptr_t)&stat;
- if (Name == "fstat") return (void*)(intptr_t)&fstat;
- if (Name == "lstat") return (void*)(intptr_t)&lstat;
- if (Name == "stat64") return (void*)(intptr_t)&stat64;
- if (Name == "fstat64") return (void*)(intptr_t)&fstat64;
- if (Name == "lstat64") return (void*)(intptr_t)&lstat64;
- if (Name == "atexit") return (void*)(intptr_t)&atexit;
- if (Name == "mknod") return (void*)(intptr_t)&mknod;
-#endif // __linux__
-
- const char *NameStr = Name.c_str();
- void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
- if (Ptr) return Ptr;
-
- // If it wasn't found and if it starts with an underscore ('_') character,
- // try again without the underscore.
- if (NameStr[0] == '_') {
- Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1);
- if (Ptr) return Ptr;
- }
-
- if (AbortOnFailure)
- report_fatal_error("Program used external function '" + Name +
- "' which could not be resolved!");
- return 0;
-}
-
-SectionMemoryManager::~SectionMemoryManager() {
- for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
- sys::Memory::ReleaseRWX(AllocatedCodeMem[i]);
- for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i)
- free(AllocatedDataMem[i].base());
-}
-
-} // namespace llvm
diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
deleted file mode 100644
index e44217c..0000000
--- a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===-- SectionMemoryManager.h - Memory allocator for MCJIT -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the declaration of a section-based memory manager used by
-// the MCJIT execution engine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
-#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Memory.h"
-
-namespace llvm {
-
-// Section-based memory manager for MCJIT
-class SectionMemoryManager : public JITMemoryManager {
-
-public:
-
- SectionMemoryManager() { }
- ~SectionMemoryManager();
-
- virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
-
- virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
-
- virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true);
-
- // Invalidate instruction cache for code sections. Some platforms with
- // separate data cache and instruction cache require explicit cache flush,
- // otherwise JIT code manipulations (like resolved relocations) will get to
- // the data cache but not to the instruction cache.
- virtual void invalidateInstructionCache();
-
-private:
-
- SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
- SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
- SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
-
-public:
-
- ///
- /// Functions below are not used by MCJIT, but must be implemented because
- /// they are declared as pure virtuals in the base class.
- ///
-
- virtual void setMemoryWritable() {
- llvm_unreachable("Unexpected call!");
- }
- virtual void setMemoryExecutable() {
- llvm_unreachable("Unexpected call!");
- }
- virtual void setPoisonMemory(bool poison) {
- llvm_unreachable("Unexpected call!");
- }
- virtual void AllocateGOT() {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *getGOTBase() const {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *startFunctionBody(const Function *F,
- uintptr_t &ActualSize){
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void deallocateFunctionBody(void *Body) {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *startExceptionTable(const Function *F,
- uintptr_t &ActualSize) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
- uint8_t *TableEnd, uint8_t *FrameRegister) {
- llvm_unreachable("Unexpected call!");
- }
- virtual void deallocateExceptionTable(void *ET) {
- llvm_unreachable("Unexpected call!");
- }
-};
-
-}
-
-#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index ca11956..c779a6a 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -10,7 +10,10 @@
LEVEL = ../..
TESTNAME = ExecutionEngine
LINK_COMPONENTS :=interpreter
-PARALLEL_DIRS = JIT MCJIT
+
+ifeq ($(TARGET_HAS_JIT),1)
+ PARALLEL_DIRS = JIT MCJIT
+endif
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
OpenPOWER on IntegriCloud