From 0a962314fb5b3e9654ad9ab50b7d1b684f154270 Mon Sep 17 00:00:00 2001 From: Jeffrey Yasskin Date: Tue, 4 Aug 2009 23:53:16 +0000 Subject: Make ExecutionEngine::updateGlobalMapping(GV, NULL) properly remove GV's old address from the reverse mapping, and add a test that this works now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78127 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/ExecutionEngine.cpp | 2 +- unittests/ExecutionEngine/ExecutionEngineTest.cpp | 92 +++++++++++++++++++++++ unittests/ExecutionEngine/Makefile | 7 +- 3 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 unittests/ExecutionEngine/ExecutionEngineTest.cpp diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 8a999da3d3..e827d36f86 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -179,7 +179,7 @@ void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) { } if (!state.getGlobalAddressReverseMap(locked).empty()) - state.getGlobalAddressReverseMap(locked).erase(Addr); + state.getGlobalAddressReverseMap(locked).erase(OldVal); return OldVal; } diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp new file mode 100644 index 0000000000..8478ebd230 --- /dev/null +++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp @@ -0,0 +1,92 @@ +//===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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 "gtest/gtest.h" + +using namespace llvm; + +namespace { + +class ExecutionEngineTest : public testing::Test { +protected: + ExecutionEngineTest() + : M(new Module("
", getGlobalContext())), + Engine(EngineBuilder(M).create()) { + } + + virtual void SetUp() { + ASSERT_TRUE(Engine.get() != NULL); + } + + GlobalVariable *NewExtGlobal(const Type *T, const Twine &Name) { + return new GlobalVariable(*M, T, false, // Not constant. + GlobalValue::ExternalLinkage, NULL, Name); + } + + Module *const M; + const OwningPtr Engine; +}; + +TEST_F(ExecutionEngineTest, ForwardGlobalMapping) { + GlobalVariable *G1 = NewExtGlobal(Type::Int32Ty, "Global1"); + int32_t Mem1 = 3; + Engine->addGlobalMapping(G1, &Mem1); + EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1)); + int32_t Mem2 = 4; + Engine->updateGlobalMapping(G1, &Mem2); + EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1)); + Engine->updateGlobalMapping(G1, NULL); + EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G1)); + Engine->updateGlobalMapping(G1, &Mem2); + EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1)); + + GlobalVariable *G2 = NewExtGlobal(Type::Int32Ty, "Global1"); + EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G2)) + << "The NULL return shouldn't depend on having called" + << " updateGlobalMapping(..., NULL)"; + // Check that update...() can be called before add...(). + Engine->updateGlobalMapping(G2, &Mem1); + EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2)); + EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1)) + << "A second mapping shouldn't affect the first."; +} + +TEST_F(ExecutionEngineTest, ReverseGlobalMapping) { + GlobalVariable *G1 = NewExtGlobal(Type::Int32Ty, "Global1"); + + int32_t Mem1 = 3; + Engine->addGlobalMapping(G1, &Mem1); + EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1)); + int32_t Mem2 = 4; + Engine->updateGlobalMapping(G1, &Mem2); + EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1)); + EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2)); + + GlobalVariable *G2 = NewExtGlobal(Type::Int32Ty, "Global2"); + Engine->updateGlobalMapping(G2, &Mem1); + EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1)); + EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2)); + Engine->updateGlobalMapping(G1, NULL); + EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1)) + << "Removing one mapping doesn't affect a different one."; + EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem2)); + Engine->updateGlobalMapping(G2, &Mem2); + EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1)); + EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2)) + << "Once a mapping is removed, we can point another GV at the" + << " now-free address."; +} + +} diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile index e837a7d4fd..d4ef92ffb3 100644 --- a/unittests/ExecutionEngine/Makefile +++ b/unittests/ExecutionEngine/Makefile @@ -8,12 +8,11 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. +TESTNAME = ExecutionEngine +LINK_COMPONENTS := engine interpreter include $(LEVEL)/Makefile.config PARALLEL_DIRS = JIT -include $(LEVEL)/Makefile.common - -clean:: - $(Verb) $(RM) -f *Tests +include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest -- cgit v1.2.3