Minor changes to the MCJITTest unittests to use the correct API for finalizing
authorDavid Tweed <david.tweed@arm.com>
Fri, 17 May 2013 10:01:46 +0000 (10:01 +0000)
committerDavid Tweed <david.tweed@arm.com>
Fri, 17 May 2013 10:01:46 +0000 (10:01 +0000)
the JIT object (including XFAIL an ARM test that now needs fixing). Also renames
internal function for consistency.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182085 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/llvm/ExecutionEngine/ExecutionEngine.h
include/llvm/ExecutionEngine/RuntimeDyld.h
include/llvm/ExecutionEngine/SectionMemoryManager.h
lib/ExecutionEngine/JIT/JITMemoryManager.cpp
lib/ExecutionEngine/MCJIT/MCJIT.cpp
lib/ExecutionEngine/MCJIT/MCJIT.h
lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
tools/lli/RecordingMemoryManager.h
tools/llvm-rtdyld/llvm-rtdyld.cpp
unittests/ExecutionEngine/JIT/JITTest.cpp
unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
unittests/ExecutionEngine/MCJIT/MCJITTest.cpp

index 83a672de2b698c9f28c5e108ed17c497bde242a2..ceac298655e85bce87079ff73bf4579382b30c89 100644 (file)
@@ -252,11 +252,14 @@ public:
                      "EE!");
   }
 
-  // finalizeObject - This method should be called after sections within an
-  // object have been relocated using mapSectionAddress.  When this method is
-  // called the MCJIT execution engine will reapply relocations for a loaded
-  // object.  This method has no effect for the legacy JIT engine or the
-  // interpeter.
+  /// finalizeObject - ensure the module is fully processed and is usable.
+  ///
+  /// It is the user-level function for completing the process of making the
+  /// object usable for execution.  It should be called after sections within an
+  /// object have been relocated using mapSectionAddress.  When this method is
+  /// called the MCJIT execution engine will reapply relocations for a loaded
+  /// object.  This method has no effect for the legacy JIT engine or the
+  /// interpeter.
   virtual void finalizeObject() {}
 
   /// runStaticConstructorsDestructors - This method is used to execute all of
index c6c126c6e242e2ad66e51799d8026b5d9ec4ab43..7dba040961a29341026a05e7871471846af6a556 100644 (file)
@@ -62,10 +62,12 @@ public:
   /// permissions can be applied.  It is up to the memory manager implementation
   /// to decide whether or not to act on this method.  The memory manager will
   /// typically allocate all sections as read-write and then apply specific
-  /// permissions when this method is called.
+  /// permissions when this method is called.  Code sections cannot be executed
+  /// until this function has been called.  In addition, any cache coherency
+  /// operations needed to reliably use the memory are also performed.
   ///
   /// Returns true if an error occurred, false otherwise.
-  virtual bool applyPermissions(std::string *ErrMsg = 0) = 0;
+  virtual bool finalizeMemory(std::string *ErrMsg = 0) = 0;
 
   /// Register the EH frames with the runtime so that c++ exceptions work. The
   /// default implementation does nothing. Look at SectionMemoryManager for one
index 305a96619a0d2513cad2f34e769d44cbb08d04ae..fc8dacfcc0900998d90a8343f41f6508e5c45e37 100644 (file)
@@ -33,7 +33,7 @@ namespace llvm {
 /// Any client using this memory manager MUST ensure that section-specific
 /// page permissions have been applied before attempting to execute functions
 /// in the JITed object.  Permissions can be applied either by calling
-/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions
+/// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory
 /// directly.  Clients of MCJIT should call MCJIT::finalizeObject.
 class SectionMemoryManager : public RTDyldMemoryManager {
   SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
@@ -60,17 +60,18 @@ public:
                                        unsigned SectionID,
                                        bool isReadOnly);
 
-  /// \brief Applies section-specific memory permissions.
+  /// \brief Update section-specific memory permissions and other attributes.
   ///
   /// This method is called when object loading is complete and section page
   /// permissions can be applied.  It is up to the memory manager implementation
   /// to decide whether or not to act on this method.  The memory manager will
   /// typically allocate all sections as read-write and then apply specific
   /// permissions when this method is called.  Code sections cannot be executed
-  /// until this function has been called.
+  /// until this function has been called.  In addition, any cache coherency
+  /// operations needed to reliably use the memory are also performed.
   ///
   /// \returns true if an error occurred, false otherwise.
-  virtual bool applyPermissions(std::string *ErrMsg = 0);
+  virtual bool finalizeMemory(std::string *ErrMsg = 0);
 
   void registerEHFrames(StringRef SectionData);
 
@@ -89,7 +90,7 @@ public:
   /// explicit cache flush, otherwise JIT code manipulations (like resolved
   /// relocations) will get to the data cache but not to the instruction cache.
   ///
-  /// This method is called from applyPermissions.
+  /// This method is called from finalizeMemory.
   virtual void invalidateInstructionCache();
 
 private:
index bf5680d832d2084ebe794849ed6ead360d8ef4b1..6a1db16a6a189f4d70beb81b36a60cd13714ae8c 100644 (file)
@@ -509,7 +509,7 @@ namespace {
       return (uint8_t*)DataAllocator.Allocate(Size, Alignment);
     }
 
-    bool applyPermissions(std::string *ErrMsg) {
+    bool finalizeMemory(std::string *ErrMsg) {
       return false;
     }
 
index ced567205aa850a51677ba2a9e2df505415b3d63..e8619385635fdd9467e858abe07ed141918a5d04 100644 (file)
@@ -178,7 +178,7 @@ void MCJIT::finalizeObject() {
     MemMgr->registerEHFrames(EHData);
 
   // Set page permissions.
-  MemMgr->applyPermissions();
+  MemMgr->finalizeMemory();
 }
 
 void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
index 7f247e2dee5b4759a079b0d071f55776b5e87412..a899d4f4080ceff2320c628c4232f2fce029d322 100644 (file)
@@ -52,6 +52,13 @@ public:
   /// Sets the object manager that MCJIT should use to avoid compilation.
   virtual void setObjectCache(ObjectCache *manager);
 
+  /// finalizeObject - ensure the module is fully processed and is usable.
+  ///
+  /// It is the user-level function for completing the process of making the
+  /// object usable for execution. It should be called after sections within an
+  /// object have been relocated using mapSectionAddress.  When this method is
+  /// called the MCJIT execution engine will reapply relocations for a loaded
+  /// object.
   virtual void finalizeObject();
 
   virtual void *getPointerToBasicBlock(BasicBlock *BB);
index bac77ce75f494c50d1e515c1d6a9415c73d035a7..1bb0103f08e1884a1a7106235be290fc6bf59d73 100644 (file)
@@ -111,7 +111,7 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup,
   return (uint8_t*)Addr;
 }
 
-bool SectionMemoryManager::applyPermissions(std::string *ErrMsg)
+bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg)
 {
   // FIXME: Should in-progress permissions be reverted if an error occurs?
   error_code ec;
index f3d026f2419c754595967594c086eb124fefb38d..b2919c39790a3ebc4689e3c0dcf2725871a56189 100644 (file)
@@ -58,7 +58,7 @@ public:
   void *getPointerToNamedFunction(const std::string &Name,
                                   bool AbortOnFailure = true);
 
-  bool applyPermissions(std::string *ErrMsg) { return false; }
+  bool finalizeMemory(std::string *ErrMsg) { return false; }
 
   // The following obsolete JITMemoryManager calls are stubbed out for
   // this model.
index ead541a5b80fa46482a7699e6e7142e7b07c55a7..b68f2a08d92726d4baf7fd936f2afeb6357cacc9 100644 (file)
@@ -69,7 +69,7 @@ public:
     return 0;
   }
 
-  bool applyPermissions(std::string *ErrMsg) { return false; }
+  bool finalizeMemory(std::string *ErrMsg) { return false; }
 
   // Invalidate instruction cache for sections with execute permissions.
   // Some platforms with separate data cache and instruction cache require
index cf995aac7a1a06e8e012400c23443e0dfc64c2c2..f8d9da2755031f083843b1b04eaac0e2ca0dc8ba 100644 (file)
@@ -127,7 +127,7 @@ public:
                                        unsigned SectionID) {
     return Base->allocateCodeSection(Size, Alignment, SectionID);
   }
-  virtual bool applyPermissions(std::string *ErrMsg) { return false; }
+  virtual bool finalizeMemory(std::string *ErrMsg) { return false; }
   virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
     return Base->allocateSpace(Size, Alignment);
   }
index ab09acad0d3b65c6366a44c79eb1302071078bb8..9e0b35395e506646409b7258832c1b0f144972a3 100644 (file)
@@ -46,7 +46,7 @@ TEST(MCJITMemoryManagerTest, BasicAllocations) {
   }\r
 \r
   std::string Error;\r
-  EXPECT_FALSE(MemMgr->applyPermissions(&Error));\r
+  EXPECT_FALSE(MemMgr->finalizeMemory(&Error));\r
 }\r
 \r
 TEST(MCJITMemoryManagerTest, LargeAllocations) {\r
@@ -79,7 +79,7 @@ TEST(MCJITMemoryManagerTest, LargeAllocations) {
   }\r
 \r
   std::string Error;\r
-  EXPECT_FALSE(MemMgr->applyPermissions(&Error));\r
+  EXPECT_FALSE(MemMgr->finalizeMemory(&Error));\r
 }\r
 \r
 TEST(MCJITMemoryManagerTest, ManyAllocations) {\r
@@ -114,7 +114,7 @@ TEST(MCJITMemoryManagerTest, ManyAllocations) {
   }\r
 \r
   std::string Error;\r
-  EXPECT_FALSE(MemMgr->applyPermissions(&Error));\r
+  EXPECT_FALSE(MemMgr->finalizeMemory(&Error));\r
 }\r
 \r
 TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {\r
index abe8be450ae91e0d1a01aa7039d7c2bf13d8577c..32fc292496c55afe0e55760c4f674885026dadb5 100644 (file)
@@ -101,11 +101,10 @@ protected:
     ASSERT_TRUE(TheJIT.isValid());
     ASSERT_TRUE(0 != Main);
 
+    // We may be using a null cache, so ensure compilation is valid.
     TheJIT->finalizeObject();
     void *vPtr = TheJIT->getPointerToFunction(Main);
 
-    static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
-
     EXPECT_TRUE(0 != vPtr)
       << "Unable to get pointer to main() from JIT";
 
index e9cf904b1813fc8f2a7c6316e52d87a6673a3b0c..43a82984c45840c647573d4a9ef06388e74e861e 100644 (file)
@@ -34,6 +34,7 @@ namespace {
 /*
 TEST_F(MCJITTest, empty_module) {
   createJIT(M.take());
+  TheJIT->finalizeObject();
   //EXPECT_NE(0, TheJIT->getObjectImage())
   //  << "Unable to generate executable loaded object image";
 }
@@ -46,8 +47,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();
+  TheJIT->finalizeObject();
   EXPECT_TRUE(0 != globalPtr)
     << "Unable to get pointer to global value from JIT";
 
@@ -61,8 +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();
+  TheJIT->finalizeObject();
   EXPECT_TRUE(0 != addPtr)
     << "Unable to get pointer to function from JIT";
 
@@ -79,8 +78,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();
+  TheJIT->finalizeObject();
   EXPECT_TRUE(0 != vPtr)
     << "Unable to get pointer to main() from JIT";
 
@@ -102,8 +100,7 @@ TEST_F(MCJITTest, return_global) {
 
   createJIT(M.take());
   void *rgvPtr = TheJIT->getPointerToFunction(ReturnGlobal);
-  MM->applyPermissions();
-  static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
+  TheJIT->finalizeObject();
   EXPECT_TRUE(0 != rgvPtr);
 
   int32_t(*FuncPtr)(void) = (int32_t(*)(void))(intptr_t)rgvPtr;
@@ -134,6 +131,7 @@ TEST_F(MCJITTest, increment_global) {
 
   createJIT(M.take());
   void *gvPtr = TheJIT->getPointerToGlobal(GV);
+  TheJIT->finalizeObject();
   EXPECT_EQ(initialNum, *(int32_t*)gvPtr);
 
   void *vPtr = TheJIT->getPointerToFunction(IncrementGlobal);
@@ -150,6 +148,9 @@ TEST_F(MCJITTest, increment_global) {
 }
 */
 
+// PR16013: XFAIL this test on ARM, which currently can't handle multiple relocations.
+#if !defined(__arm__)
+
 TEST_F(MCJITTest, multiple_functions) {
   SKIP_UNSUPPORTED_PLATFORM;
 
@@ -172,8 +173,7 @@ TEST_F(MCJITTest, multiple_functions) {
 
   createJIT(M.take());
   void *vPtr = TheJIT->getPointerToFunction(Outer);
-  MM->applyPermissions();
-  static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
+  TheJIT->finalizeObject();
   EXPECT_TRUE(0 != vPtr)
     << "Unable to get pointer to outer function from JIT";
 
@@ -182,6 +182,8 @@ TEST_F(MCJITTest, multiple_functions) {
     << "Incorrect result returned from function";
 }
 
+#endif /*!defined(__arm__)*/
+
 // FIXME: ExecutionEngine has no support empty modules
 /*
 TEST_F(MCJITTest, multiple_empty_modules) {
@@ -219,6 +221,7 @@ TEST_F(MCJITTest, multiple_modules) {
 
   // get a function pointer in a module that was not used in EE construction
   void *vPtr = TheJIT->getPointerToFunction(Caller);
+  TheJIT->finalizeObject();
   EXPECT_NE(0, vPtr)
     << "Unable to get pointer to caller function from JIT";