11c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor//===- MCJITObjectCacheTest.cpp - Unit tests for MCJIT object caching -----===// 21c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor// 31c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor// The LLVM Compiler Infrastructure 41c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor// 51c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor// This file is distributed under the University of Illinois Open Source 61c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor// License. See LICENSE.TXT for details. 71c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor// 81c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor//===----------------------------------------------------------------------===// 91c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCJITTestBase.h" 111c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ADT/SmallVector.h" 121c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ADT/StringMap.h" 131c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ADT/StringSet.h" 141c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ExecutionEngine/JIT.h" 151c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ExecutionEngine/MCJIT.h" 161c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ExecutionEngine/ObjectCache.h" 171c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "llvm/ExecutionEngine/SectionMemoryManager.h" 181c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor#include "gtest/gtest.h" 191c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 201c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorusing namespace llvm; 211c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 221c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylornamespace { 231c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 241c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorclass TestObjectCache : public ObjectCache { 251c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorpublic: 261c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TestObjectCache() : DuplicateInserted(false) { } 271c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 281c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor virtual ~TestObjectCache() { 291c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Free any buffers we've allocated. 306227d5c690504c7ada5780c00a635b282c46e275Craig Topper SmallVectorImpl<MemoryBuffer *>::iterator it, end; 311c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor end = AllocatedBuffers.end(); 321c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor for (it = AllocatedBuffers.begin(); it != end; ++it) { 331c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor delete *it; 341c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 351c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor AllocatedBuffers.clear(); 361c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 371c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 381c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) { 391c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // If we've seen this module before, note that. 401c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const std::string ModuleID = M->getModuleIdentifier(); 411c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (ObjMap.find(ModuleID) != ObjMap.end()) 421c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor DuplicateInserted = true; 431c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Store a copy of the buffer in our map. 441c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjMap[ModuleID] = copyBuffer(Obj); 451c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 461c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 4740d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor virtual MemoryBuffer* getObject(const Module* M) { 4840d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor const MemoryBuffer* BufferFound = getObjectInternal(M); 4940d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor ModulesLookedUp.insert(M->getModuleIdentifier()); 5040d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor if (!BufferFound) 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return nullptr; 5240d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor // Our test cache wants to maintain ownership of its object buffers 5340d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor // so we make a copy here for the execution engine. 5440d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor return MemoryBuffer::getMemBufferCopy(BufferFound->getBuffer()); 5540d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor } 5640d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor 571c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Test-harness-specific functions 581c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor bool wereDuplicatesInserted() { return DuplicateInserted; } 591c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 601c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor bool wasModuleLookedUp(const Module *M) { 611c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor return ModulesLookedUp.find(M->getModuleIdentifier()) 621c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor != ModulesLookedUp.end(); 631c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 641c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 651c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const MemoryBuffer* getObjectInternal(const Module* M) { 661c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Look for the module in our map. 671c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const std::string ModuleID = M->getModuleIdentifier(); 681c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor StringMap<const MemoryBuffer *>::iterator it = ObjMap.find(ModuleID); 691c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (it == ObjMap.end()) 70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return nullptr; 711c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor return it->second; 721c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 731c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 741c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorprivate: 751c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor MemoryBuffer *copyBuffer(const MemoryBuffer *Buf) { 761c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a local copy of the buffer. 771c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor MemoryBuffer *NewBuffer = MemoryBuffer::getMemBufferCopy(Buf->getBuffer()); 781c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor AllocatedBuffers.push_back(NewBuffer); 791c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor return NewBuffer; 801c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 811c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 821c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor StringMap<const MemoryBuffer *> ObjMap; 831c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor StringSet<> ModulesLookedUp; 841c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor SmallVector<MemoryBuffer *, 2> AllocatedBuffers; 851c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor bool DuplicateInserted; 861c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor}; 871c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 881c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorclass MCJITObjectCacheTest : public testing::Test, public MCJITTestBase { 891c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorprotected: 901c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 911c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor enum { 921c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor OriginalRC = 6, 931c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ReplacementRC = 7 941c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor }; 951c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 961c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor virtual void SetUp() { 971c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor M.reset(createEmptyModule("<main>")); 981c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor Main = insertMainFunction(M.get(), OriginalRC); 991c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 1001c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1011c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor void compileAndRun(int ExpectedRC = OriginalRC) { 1021c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // This function shouldn't be called until after SetUp. 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASSERT_TRUE(bool(TheJIT)); 104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ASSERT_TRUE(nullptr != Main); 1051c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 106abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed // We may be using a null cache, so ensure compilation is valid. 1071c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->finalizeObject(); 1081c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor void *vPtr = TheJIT->getPointerToFunction(Main); 1091c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_TRUE(nullptr != vPtr) 1111c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor << "Unable to get pointer to main() from JIT"; 1121c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1131c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor int (*FuncPtr)(void) = (int(*)(void))(intptr_t)vPtr; 1141c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor int returnCode = FuncPtr(); 1151c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_EQ(returnCode, ExpectedRC); 1161c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 1171c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1181c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor Function *Main; 1191c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor}; 1201c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1211c489455ea5fac43a5f20911dfb5486630eb0160Andrew KaylorTEST_F(MCJITObjectCacheTest, SetNullObjectCache) { 1221c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 1231c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createJIT(M.release()); 1251c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TheJIT->setObjectCache(nullptr); 1271c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1281c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor compileAndRun(); 1291c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} 1301c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1311c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1321c489455ea5fac43a5f20911dfb5486630eb0160Andrew KaylorTEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) { 1331c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 1341c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<TestObjectCache> Cache(new TestObjectCache); 1361c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1371c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Save a copy of the module pointer before handing it off to MCJIT. 1381c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const Module * SavedModulePointer = M.get(); 1391c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createJIT(M.release()); 1411c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1421c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->setObjectCache(Cache.get()); 1431c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1441c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that our object cache does not contain the module yet. 1451c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SavedModulePointer); 146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, ObjBuffer); 1471c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1481c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor compileAndRun(); 1491c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1501c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that MCJIT tried to look-up this module in the cache. 1511c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_TRUE(Cache->wasModuleLookedUp(SavedModulePointer)); 1521c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1531c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that our object cache now contains the module. 1541c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjBuffer = Cache->getObjectInternal(SavedModulePointer); 155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_TRUE(nullptr != ObjBuffer); 1561c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1571c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that the cache was only notified once. 1581c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_FALSE(Cache->wereDuplicatesInserted()); 1591c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} 1601c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1611c489455ea5fac43a5f20911dfb5486630eb0160Andrew KaylorTEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) { 1621c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 1631c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<TestObjectCache> Cache(new TestObjectCache); 1651c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1661c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Compile this module with an MCJIT engine 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createJIT(M.release()); 1681c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->setObjectCache(Cache.get()); 1691c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->finalizeObject(); 1701c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1711c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Destroy the MCJIT engine we just used 1721c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT.reset(); 1731c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1741c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a new memory manager. 1751c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor MM = new SectionMemoryManager; 1761c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1771c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a new module and save it. Use a different return code so we can 1781c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // tell if MCJIT compiled this module or used the cache. 1791c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor M.reset(createEmptyModule("<main>")); 1801c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor Main = insertMainFunction(M.get(), ReplacementRC); 1811c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const Module * SecondModulePointer = M.get(); 1821c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1831c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a new MCJIT instance to load this module then execute it. 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createJIT(M.release()); 1851c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->setObjectCache(Cache.get()); 1861c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor compileAndRun(); 1871c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1881c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that MCJIT tried to look-up this module in the cache. 1891c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_TRUE(Cache->wasModuleLookedUp(SecondModulePointer)); 1901c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1911c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that MCJIT didn't try to cache this again. 1921c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_FALSE(Cache->wereDuplicatesInserted()); 1931c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} 1941c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1951c489455ea5fac43a5f20911dfb5486630eb0160Andrew KaylorTEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) { 1961c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 1971c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<TestObjectCache> Cache(new TestObjectCache); 1991c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2001c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Compile this module with an MCJIT engine 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createJIT(M.release()); 2021c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->setObjectCache(Cache.get()); 2031c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->finalizeObject(); 2041c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2051c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Destroy the MCJIT engine we just used 2061c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT.reset(); 2071c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2081c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a new memory manager. 2091c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor MM = new SectionMemoryManager; 2101c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2111c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a new module and save it. Use a different return code so we can 2121c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // tell if MCJIT compiled this module or used the cache. Note that we use 2131c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // a new module name here so the module shouldn't be found in the cache. 2141c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor M.reset(createEmptyModule("<not-main>")); 2151c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor Main = insertMainFunction(M.get(), ReplacementRC); 2161c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const Module * SecondModulePointer = M.get(); 2171c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2181c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Create a new MCJIT instance to load this module then execute it. 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createJIT(M.release()); 2201c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor TheJIT->setObjectCache(Cache.get()); 2211c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2221c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that our object cache does not contain the module yet. 2231c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SecondModulePointer); 224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, ObjBuffer); 2251c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2261c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Run the function and look for the replacement return code. 2271c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor compileAndRun(ReplacementRC); 2281c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2291c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that MCJIT tried to look-up this module in the cache. 2301c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_TRUE(Cache->wasModuleLookedUp(SecondModulePointer)); 2311c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2321c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that our object cache now contains the module. 2331c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjBuffer = Cache->getObjectInternal(SecondModulePointer); 234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_TRUE(nullptr != ObjBuffer); 2351c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2361c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Verify that MCJIT didn't try to cache this again. 2371c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor EXPECT_FALSE(Cache->wereDuplicatesInserted()); 2381c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} 2391c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 2401c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} // Namespace 2411c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 242