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