//===- MCJITObjectCacheTest.cpp - Unit tests for MCJIT object caching -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCJITTestBase.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

class TestObjectCache : public ObjectCache {
public:
  TestObjectCache() : DuplicateInserted(false) { }

  virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) {
    // If we've seen this module before, note that.
    const std::string ModuleID = M->getModuleIdentifier();
    if (ObjMap.find(ModuleID) != ObjMap.end())
      DuplicateInserted = true;
    // Store a copy of the buffer in our map.
    ObjMap[ModuleID] = copyBuffer(Obj);
  }

  virtual std::unique_ptr<MemoryBuffer> getObject(const Module* M) {
    const MemoryBuffer* BufferFound = getObjectInternal(M);
    ModulesLookedUp.insert(M->getModuleIdentifier());
    if (!BufferFound)
      return nullptr;
    // Our test cache wants to maintain ownership of its object buffers
    // so we make a copy here for the execution engine.
    return std::unique_ptr<MemoryBuffer>(
        MemoryBuffer::getMemBufferCopy(BufferFound->getBuffer()));
  }

  // Test-harness-specific functions
  bool wereDuplicatesInserted() { return DuplicateInserted; }

  bool wasModuleLookedUp(const Module *M) {
    return ModulesLookedUp.find(M->getModuleIdentifier())
                                      != ModulesLookedUp.end();
  }

  const MemoryBuffer* getObjectInternal(const Module* M) {
    // Look for the module in our map.
    const std::string ModuleID = M->getModuleIdentifier();
    StringMap<const MemoryBuffer *>::iterator it = ObjMap.find(ModuleID);
    if (it == ObjMap.end())
      return nullptr;
    return it->second;
  }

private:
  MemoryBuffer *copyBuffer(const MemoryBuffer *Buf) {
    // Create a local copy of the buffer.
    std::unique_ptr<MemoryBuffer> NewBuffer(
        MemoryBuffer::getMemBufferCopy(Buf->getBuffer()));
    MemoryBuffer *Ret = NewBuffer.get();
    AllocatedBuffers.push_back(std::move(NewBuffer));
    return Ret;
  }

  StringMap<const MemoryBuffer *> ObjMap;
  StringSet<>                     ModulesLookedUp;
  SmallVector<std::unique_ptr<MemoryBuffer>, 2> AllocatedBuffers;
  bool                            DuplicateInserted;
};

class MCJITObjectCacheTest : public testing::Test, public MCJITTestBase {
protected:

  enum {
    OriginalRC = 6,
    ReplacementRC = 7
  };

  virtual void SetUp() {
    M.reset(createEmptyModule("<main>"));
    Main = insertMainFunction(M.get(), OriginalRC);
  }

  void compileAndRun(int ExpectedRC = OriginalRC) {
    // This function shouldn't be called until after SetUp.
    ASSERT_TRUE(bool(TheJIT));
    ASSERT_TRUE(nullptr != Main);

    // We may be using a null cache, so ensure compilation is valid.
    TheJIT->finalizeObject();
    void *vPtr = TheJIT->getPointerToFunction(Main);

    EXPECT_TRUE(nullptr != vPtr)
      << "Unable to get pointer to main() from JIT";

    int (*FuncPtr)(void) = (int(*)(void))(intptr_t)vPtr;
    int returnCode = FuncPtr();
    EXPECT_EQ(returnCode, ExpectedRC);
  }

  Function *Main;
};

TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
  SKIP_UNSUPPORTED_PLATFORM;

  createJIT(std::move(M));

  TheJIT->setObjectCache(nullptr);

  compileAndRun();
}


TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
  SKIP_UNSUPPORTED_PLATFORM;

  std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);

  // Save a copy of the module pointer before handing it off to MCJIT.
  const Module * SavedModulePointer = M.get();

  createJIT(std::move(M));

  TheJIT->setObjectCache(Cache.get());

  // Verify that our object cache does not contain the module yet.
  const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SavedModulePointer);
  EXPECT_EQ(nullptr, ObjBuffer);

  compileAndRun();

  // Verify that MCJIT tried to look-up this module in the cache.
  EXPECT_TRUE(Cache->wasModuleLookedUp(SavedModulePointer));

  // Verify that our object cache now contains the module.
  ObjBuffer = Cache->getObjectInternal(SavedModulePointer);
  EXPECT_TRUE(nullptr != ObjBuffer);

  // Verify that the cache was only notified once.
  EXPECT_FALSE(Cache->wereDuplicatesInserted());
}

TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
  SKIP_UNSUPPORTED_PLATFORM;

  std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);

  // Compile this module with an MCJIT engine
  createJIT(std::move(M));
  TheJIT->setObjectCache(Cache.get());
  TheJIT->finalizeObject();

  // Destroy the MCJIT engine we just used
  TheJIT.reset();

  // Create a new memory manager.
  MM = new SectionMemoryManager;

  // Create a new module and save it. Use a different return code so we can
  // tell if MCJIT compiled this module or used the cache.
  M.reset(createEmptyModule("<main>"));
  Main = insertMainFunction(M.get(), ReplacementRC);
  const Module * SecondModulePointer = M.get();

  // Create a new MCJIT instance to load this module then execute it.
  createJIT(std::move(M));
  TheJIT->setObjectCache(Cache.get());
  compileAndRun();

  // Verify that MCJIT tried to look-up this module in the cache.
  EXPECT_TRUE(Cache->wasModuleLookedUp(SecondModulePointer));

  // Verify that MCJIT didn't try to cache this again.
  EXPECT_FALSE(Cache->wereDuplicatesInserted());
}

TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
  SKIP_UNSUPPORTED_PLATFORM;

  std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);

  // Compile this module with an MCJIT engine
  createJIT(std::move(M));
  TheJIT->setObjectCache(Cache.get());
  TheJIT->finalizeObject();

  // Destroy the MCJIT engine we just used
  TheJIT.reset();

  // Create a new memory manager.
  MM = new SectionMemoryManager;

  // Create a new module and save it. Use a different return code so we can
  // tell if MCJIT compiled this module or used the cache. Note that we use
  // a new module name here so the module shouldn't be found in the cache.
  M.reset(createEmptyModule("<not-main>"));
  Main = insertMainFunction(M.get(), ReplacementRC);
  const Module * SecondModulePointer = M.get();

  // Create a new MCJIT instance to load this module then execute it.
  createJIT(std::move(M));
  TheJIT->setObjectCache(Cache.get());

  // Verify that our object cache does not contain the module yet.
  const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SecondModulePointer);
  EXPECT_EQ(nullptr, ObjBuffer);

  // Run the function and look for the replacement return code.
  compileAndRun(ReplacementRC);

  // Verify that MCJIT tried to look-up this module in the cache.
  EXPECT_TRUE(Cache->wasModuleLookedUp(SecondModulePointer));

  // Verify that our object cache now contains the module.
  ObjBuffer = Cache->getObjectInternal(SecondModulePointer);
  EXPECT_TRUE(nullptr != ObjBuffer);

  // Verify that MCJIT didn't try to cache this again.
  EXPECT_FALSE(Cache->wereDuplicatesInserted());
}

} // Namespace

